home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Scene 96
/
Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso
/
player
/
dplay300
/
eos300.doc
< prev
next >
Wrap
Text File
|
1996-12-08
|
235KB
|
5,811 lines
───────────────────────────────────────────────────────────────────────────────
┌─────────┐ ┌─────────┐ ┌─────────┐
└┐ ┌───┐ │ │ ┌───┐ │ │ ┌────┐ │
│ │ └─┘ │ │ │ │ │ │ └─┘
│ └──┐ │ │ │ │ │ └──────┐
│ ┌──┘ │ │ │ │ └──────┐ │
│ │ ┌─┐ │ │ │ │ ┌─┐ │ │
┌┘ └───┘ │ │ └───┘ │ │ └────┘ │
└─────────┘ └─────────┘ └─────────┘
───────────────────────────────────────────────────────────────────────────────
───────────────────────────────────────────────────────────────────────────────
E.O.S Eclipse Operating System Version 3.00 Bêta
Copyright (c) Eclipse 1995-96
───────────────────────────────────────────────────────────────────────────────
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Nouveautés de la version 3.00 ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
* Un seul fichier E.O.S (plus de fichier kernel).
* Compatibilité totale avec Windows 95, Windows 3.1 et Dos.
* Nouvelles librairies pour les utilisateurs de WATCOM C++.
* Possibilité d'utiliser l'E.O.S à la place de DOS4GW.
* Support du VESA 2.0 (Linear frame buffer).
* Support du VESA 1.0 (Automatic Bank Switching) en lecture et écriture.
* Nouvelle interruption pour remapper la mémoire.
* Nouveau debugger en externe pour tracer des programmes au format LE.
* Serveur DPMI Version 0.90.
* Nouvelle gestion de la mémoire par handle.
* Possibilité de linker des données sans les compresser.
* Possibilité d'utiliser l'E.O.S en externe sous WATCOM (WSTUB).
* Nouvelle fonction de synchronisation beaucoup plus stable sous
Windows 95.
* Nouveau player de module :
- Mixage automatique sur 8 ou 16bits en fonction de la carte.
- Meilleure restitution sonore sur les cartes Sound Blaster.
- Support de la Windows Sound System.
- Gestion des samples indépendamment de la musique.
- Détection manuelle ou automatique des cartes sonores.
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Table des matières ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Présentation des différents modules de l'E.O.S
Comment créer un fichier OBJ
Comment créer un fichier EXE
Utilisation d'un fichier makefile avec Turbo Assembler
Utilisation d'un fichier makefile avec WATCOM C++
Le fichier include
Les différentes fonctionnalités de l'E.O.S
Les déclarations générales
La gestion mémoire
Les fonctions pour la gestion mémoire
│Allocate Memory
│DeAllocate Memory
│Allocate Memory Handle
│DeAllocate Memory Handle
│Resize Memory Handle
│Allocate Selector
│DeAllocate Selector
│Physical Address Mapping
│Free Physical Address Mapping
La gestion de fichiers
Les fonctions pour la gestion de fichiers
│Load Internal File
│Load External File
│Load Internal File Handle
│Load External File Handle
│Write External File
La gestion des cartes sonores
Comment accéder aux différentes variables d'un module
Les effets sonores
Absence de carte sonores
Les déclarations du player de module
Les fonctions pour jouer une musique ou des effets sonores
│Detect Sound Card
│Manual Setup
│Load Module
│Play Module
│Stop Module
│Clear Module
│Set Volume
│Play Sample
│Get Info
│Set Pattern
Gestion d'un second écran monochrome
Les fonctions pour utiliser un second écran pour le debuggage
│Set Mono
│Set String Mono
│Set Value Mono
Le clavier
│Use Int 09
Synchronisation avec le balayage
Les fonctions de synchronisations
│Wait Vbl
│Use Int 08
│Change Synchro Int 08
Les variables
│Code32 Sel
│Data32 Sel
│Flat Data Sel
│Flat Code Sel
│Sélecteur 40h
│Real DS
│Real ES
│Real FS
│Real GS
│Real SS
│Real SP
│0b0000h
│0b8000h
│0a0000h
Les Macros
│Colors
│Get Param
│Send
│DosInt
│DosCall
│Init ES DI
│Init DS DX
Le mode réel
Les interruptions
Les IRQ ou interruptions matérielles
Les Exceptions
Les fonctions pour gérer les interruptions
│Get Int
│Set Int
│Get Irq
│Set Irq
Le linker
Le Debugger 32 bits
Les fonctions du Debuggeur 32 bits
│Debug
│Debug Back
Appel du debugger par Break point
│Break Point
Restitution automatique de l'environement de départ
Les fonctions système
│Exit Error
│Restore Video Mode
│Detect Windows
│Direct Send
Comment développer une librairie compatible WATCOM C et E.O.S
│La gestion mémoire sous WATCOM
│Les appels aux interruptions en mode REEL
│Les variables inutilisables sous WATCOM
│Différence entre les fichiers sources
Les librairies de l'E.O.S
La librairie VESA
│Automatic Bank Switching en VESA 1.0 ou 2.0
│Linear Frame Buffer en VESA 2.0
Les fonctions de la librairie VESA
│Init Vesa
│Init Vesa2
│Init Vesa Bank
│Close Vesa Bank
│Set Bank
Les variables de la librairie VESA
│Vesa Clear Palette
Les déclarations de la librairie VESA
La librairie FLI32
Les fonctions de la librairie FLI32
│Load Fli
│Load Internal Fli
│First Frame Fli
│Next Frame Fli
│Dispose Fli
La librairie SNAP
Les fonctions de la librairie SNAP
│Init Snap
│Snap IFF
│Save IFF
La librairie JOYSTICK
Les fonctions de la librairie JOYSTICK
│Init Joystick
│Dectect Joystick
│Add Joystick
│Update Joystick
│Sub Joystick
│Upper Left
│Lower Right
│Center
Les déclarations de la librairie JOYSTICK
La librairie mémoire
Les fonctions de la librairie mémoire
│Init Memory
Les fonctions du DPMI (interruption 31h) supportées par l'E.O.S
Les fonctions du DOS (interruption 21h) supportées par l'E.O.S
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Présentation des différents modules de l'E.O.S ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
L'E.O.S est constitué de plusieurs fichiers.
───────────────────────────────────────────────────────────────────────────────
Version d'évaluation
───────────────────────────────────────────────────────────────────────────────
Les objets de base pour Tasm et Masm :
■ EOS.OBJ Le coeur du système qui supporte Diamond.
■ EOSLITE.OBJ La version allégée si vous n'utilisez pas
■ DIAMOND.OBJ Le player de module 32 voies.
■ EOS.INC Le fichier include.
Les objets de base pour WATCOM C++ :
■ WEOS.EXE Le coeur du système qui supporte Diamond.
WSTARTUP.OBJ
WATCOM.OBJ
■ WEOSLITE.EXE La version allégée si vous n'utilisez pas
le player Diamond.
■ EOS.H Le fichier include.
Le debuggeur pour Tasm, Masm et WATCOM C++ :
■ DEBUG.OBJ Pour tracer du code 32 bits.
Les outils :
■ LLINK.EXE Pour créer un seul fichier EXE compressé.
■ CRYPT.EXE Pour protéger vos données.
■ SCANCODE.EXE Pour afficher les codes du clavier.
■ 132.EXE Pour passer en mode 132 colonnes.
■ EDCONFIG.EXE Pour configurer le debugger
■ DIET.EXE Pour compresser vos données
■ DIAMOND.EXE Pour tester un module
───────────────────────────────────────────────────────────────────────────────
Version Complète
───────────────────────────────────────────────────────────────────────────────
Les objets de base pour Tasm et Masm :
■ EOS.OBJ Le coeur du système qui supporte Diamond.
■ EOSLITE.OBJ La version allégée si vous n'utilisez pas
le player Diamond.
■ DIAMOND.OBJ Le player de module 32 voies.
■ EOS.INC Le fichier include.
Les objets de base pour WATCOM C++ :
■ WEOS.EXE Le coeur du système qui supporte Diamond.
WSTARTUP.OBJ
WATCOM.OBJ
■ WEOSLITE.EXE La version allégée si vous n'utilisez pas
le player Diamond.
■ EOS.H Le fichier include.
Le debuggeur pour Tasm, Masm et WATCOM C++ :
■ DEBUG.OBJ Pour tracer du code 32 bits.
*■ MEMORY.OBJ Pour la gestion de la mémoire.
Les Librairies TASM et MASM :
*■ VESA.OBJ Pour accéder directement au buffer de la
carte graphique sans se préoccuper des
changements de bank en VESA 1.0.
*■ FLI32.OBJ Pour visualiser les fichiers FLI et FLC.
*■ SNAP.OBJ Pour la capture d'écrans 256 couleurs
au format IFF.
*■ JOYSTICK.OBJ Pour la gestion des manettes de jeux.
Les librairies pour Wactom C++ :
*■ WVESA.OBJ Pour accéder directement au buffer de la
carte graphique sans se préoccuper des
changements de bank en VESA 1.0.
*■ WFLI32.OBJ Pour visualiser les fichiers FLI et FLC.
*■ WSNAP.OBJ Pour la capture d'écrans 256 couleurs
au format IFF.
*■ WJOYSTICK.OBJ Pour la gestion des manettes de jeux.
Les outils :
■ LLINK.EXE Pour créer un seul fichier EXE compressé.
■ CRYPT.EXE Pour protéger vos données.
■ SCANCODE.EXE Pour afficher les codes du clavier.
■ 132.EXE Pour passer en mode 132 colonnes.
■ EDCONFIG.EXE Pour configurer le debugger
■ DIET.EXE Pour compresser vos données
■ DIAMOND.EXE Pour tester un module
*■ WSTUB.EXE Pour utiliser l'E.O.S en externe.
*■ WSTUBLTE.EXE Version allégée sans Diamond.
*■ WDEBUG.EXE Pour debugger des programmes au format LE.
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Comment créer un fichier OBJ ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
A partir de l'invité de MS-Dos, taper simplement :
TASM3 Mon_programme.asm /m /q /p
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Comment créer un fichier EXE ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Si vous n'utilisez pas le player de module :
TLINK eoslite+Mon_programme /3 /x
Si vous utilisez le player de module :
TLINK eos+diamond+Mon_programme /3 /x
Si vous utilisez une librairie :
TLINK eos+diamond+Ma_librairie+Mon_programme /3 /x
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Utilisation d'un fichier makefile avec Turbo Assembler ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Le programme MAKE.EXE de Borland permet d'automatiser les commandes
d'assemblage et de linkage à l'aide d'un seul fichier script.
Exemple de fichier makefile :
PRG = EXAMPLE1
RES = ..\RESOURCE
$(PRG).exe: $(PRG).obj \
@tlink $(RES)\eoslite \
$(PRG),$(PRG).EXE /3 /x
$(PRG).obj: $(PRG).asm
@tasm3 $(PRG) /m /q /p
Pour créer votre exécutable, taper simplement MAKE.
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Utilisation d'un fichier makefile avec WATCOM C++ ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Le programme WMAKE.EXE de WATCOM permet d'automatiser les commandes
d'assemblage et de linkage comme avec Make.
Exemple de fichier makefile :
PROGNAME = TEST
RES = ..\RESOURCE
CFLAGS = /i=$(%WATCOM)\H /j /mf /fpi87 /fp3 /4s /oailt -4
CC = WCC386
.c.obj:
$(CC) $(CFLAGS) $*.c
all: $(PROGNAME).exe .SYMBOLIC
$(PROGNAME).obj : $(PROGNAME).c
$(PROGNAME).exe : $(PROGNAME).obj
%create link.opt
%append link.opt FILE $(PROGNAME)
%append link.opt LIBPATH $(%WATCOM)\LIB386;$(%WATCOM)\LIB386\DOS
%append link.opt LIBRARY CLIB3S.LIB
%append link.opt LIBRARY MATH387S.LIB
%append link.opt OPTION DOSSEG
%append link.opt option osname='Eclipse Operating System'
%append link.opt name $(PROGNAME)
%append link.opt option stub=$(RES)\WEOSLITE.EXE
%append link.opt format os2 le
@wlink @link.opt
@if exist link.opt del link.opt
Pour créer votre exécutable, taper simplement WMAKE.
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Le fichier include ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Le fichier include (EOS.INC ou EOS.H) est certainement le fichier le plus
important. Il contient en effet toutes les déclarations des différentes
fonctions, macros et variables de l'E.O.S C'est grâce à lui que votre
programme est en mesure de dialoguer avec l'E.O.S.
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les différentes fonctionnalités de l'E.O.S ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Le système E.O.S dispose d'un certain nombre de fonctions très utiles que l'on
peut appeler par l'intermédiaire de l'interruption Int_EOS.
Il suffit juste d'indiquer la fonction voulue à l'aide du registre AH comme
ci-dessous :
mov ah,Fonction_a_appeler
Int_EOS
Les fonctions disponibles sont les suivantes :
EOS.OBJ
┌──────────────────────────────────────────────────────────────────────────┐
│Allocate Memory │
│DeAllocate Memory │
│Allocate Memory Handle │
│DeAllocate Memory Handle │
│Resize Memory Handle │
│Allocate Selector │
│DeAllocate Selector │
│Physical Address Mapping │
│Free Physical Address Mapping │
│ │
│Load Internal File │
│Load External File │
│Load Internal File Handle │
│Load External File Handle │
│Write External File │
│ │
│Set Mono │
│Set String Mono │
│Set Value Mono │
│ │
│Use Int 09 │
│ │
│Wait Vbl │
│Use Int 08 │
│Change Synchro Int 08 │
│ │
│Get Int │
│Set Int │
│Get Irq │
│Set Irq │
│ │
│Exit Error │
│ │
│Restore Vidèo Mode │
│ │
│Detect Windows │
│ │
│Direct Send │
└──────────────────────────────────────────────────────────────────────────┘
DIAMOND.OBJ
┌──────────────────────────────────────────────────────────────────────────┐
│Detect Sound Card │
│Manual Setup │
│Load Module │
│Play Module │
│Stop Module │
│Clear Module │
│Set Volume │
│Play Sample │
│Get Info │
│Set Pattern │
└──────────────────────────────────────────────────────────────────────────┘
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les Déclarations gébérales ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Pour faciliter l'écriture de vos programmes, l'E.O.S dispose de quelques
déclarations générales très pratiques :
On = 1
Off = 0
B = Byte Ptr
W = Word Ptr
D = Dword Ptr
F = Fword Ptr
O = Offset
Exemple :
mov edi, O File_Name
ou
mov edi, Offset File_Name
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ La gestion mémoire ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Avec l'E.O.S, finit les problèmes de mémoire ! Vous pouvez désormais adresser
linéairement toutes la mémoire disponible et cela quelques que soit la
configuration de votre système :
■ Mode RAW sans Himem.
■ Mode XMS avec Himem.
■ Mode VCPI avec EMS (Emm386 highscan).
■ Mode VCPI sans EMS (Emm386 noems).
■ Mode DPMI avec Windows 3.1x.
■ Mode DPMI avec Windows 95.
■ Mode DPMI avec OS/2 2.1 ou OS/2 Warp.
Pour allouer ou restituer de la mémoire supérieur, une simple
interruption de l 'E.O.S suffit :
Allocation sans handle :
mov ah,Allocate_Memory
mov edx,Taille_Allocation
Int_EOS
jc Not_Enough_Memory
mov [Logical_Address_Of_Block],edx
Restitution de la dernière allocation :
mov ah,DeAllocate_Memory
Int_EOS
Allocation par handle :
mov ah,Allocate_Memory_Handle
mov edx,Taille_Allocation
Int_EOS
jc Not_Enough_Memory
mov [Logical_Address_Of_Block],edx
mov [Memory_Handle],edi
Restitution par handle :
mov ah,DeAllocate_Memory_Handle
mov edi,[Memory_Handle]
Int_EOS
jc Invalid_Handle
Vous pouvez avec la même simplicité créer vos propres sélecteurs et profiter
pleinement de la segmentation du mode protégé.
Allocation d'un sélecteur :
mov ah,Allocate_Selector
mov esi,0a0000h ; Base
mov edi,0fh ; 64ko (0000-ffff)
Int_EOS
jc No_Free Selector
mov [_0a0000h_Sel],bx
Restitution d'un sélecteur :
mov ah,DeAllocate_Selector
mov bx,[_0a0000h_Sel]
Int_EOS
jc Invalid_Selector
Vous pouvez aussi remapper la mémoire pour accéder linéairement à la carte
graphique :
mov ah,Physical_Address_Mapping
mov ecx,1024*1024
mov esi,[Vesa_Linear_Address]
Int_EOS
jc Not_Enough_Memory
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les fonctions pour la gestion mémoire ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
┌─────────────────────────────┐
│Allocate Memory │
│DeAllocate Memory │
│Allocate Memory Handle │
│DeAllocate Memory Handle │
│Resize Memory Handle │
│Allocate Selector │
│DeAllocate Selector │
│Physical Address Mapping │
│Free Physical Address Mapping│
└─────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│Allocate Memory Allocate Upper memory │
│ │
│In : │
│ AH = Allocate_Memory │
│ EDX = Size of memory block to allocate in bytes │
│ │
│Out : │
│ Carry = 0 │
│ All Done │
│ EAX = Physical address of the block (work with Flat_Data_Sel) │
│ EDX = Logical address of the block (work with Data32_Sel) │
│ │
│ Carry = 1 │
│ Can't allocate memory │
│ EAX = Largest available free memory │
│ EDX = Total available memory │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Allocate_Memory
mov edx,[Allocation_Size]
Int_EOS
jc Not_Enough_Memory
mov [Physical_Address_Of_Block],eax ; Work with Flat_Data_Sel
mov [Logical_Address_Of_Block],edx ; Work with Data32_Sel
┌──────────────────────────────────────────────────────────────────────────┐
│DeAllocate Memory Free the last allocate memory │
│ │
│In : │
│ AH = DeAllocate_Memory │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,DeAllocate_Memory
Int_EOS
┌──────────────────────────────────────────────────────────────────────────┐
│Allocate Memory Handle Allocate Upper memory with handle │
│ │
│In : │
│ AH = Allocate_Memory │
│ EDX = Size of memory block to allocate in bytes │
│ │
│Out : │
│ Carry = 0 │
│ All Done │
│ EAX = Physical address of the block (work with Flat_Data_Sel) │
│ EDX = Logical address of the block (work with Data32_Sel) │
│ EDI = Handle of Memory │
│ │
│ Carry = 1 │
│ Can't allocate memory │
│ EAX = Largest available free memory │
│ EDX = Total available memory │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Allocate_Memory_Handle
mov edx,[Allocation_Size]
Int_EOS
jc Not_Enough_Memory
mov [Physical_Address_Of_Block],eax ; Work with Flat_Data_Sel
mov [Logical_Address_Of_Block],edx ; Work with Data32_Sel
mov [Memory_Handle],edi
┌──────────────────────────────────────────────────────────────────────────┐
│DeAllocate Memory Handle Free the allocate memory with this handle │
│ │
│In : │
│ AH = DeAllocate_Memory │
│ EDI = Handle of Memory │
│ │
│Out : │
│ Carry = 0 │
│ All Done │
│ │
│ Carry = 1 │
│ Invalid handle │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,DeAllocate_Memory_Handle
mov edi,[Memory_Handle]
Int_EOS
jc Invalid_Handle
┌──────────────────────────────────────────────────────────────────────────┐
│Resize Memory Handle Resize the allocate memory with this handle │
│ │
│In : │
│ AH = Resize_Memory_Handle │
│ ECX = New Size of the memory block │
│ EDI = Handle of Memory │
│ │
│Out : │
│ Carry = 0 │
│ All Done │
│ EAX = Physical address of the block (work with Flat_Data_Sel) │
│ EDX = Logical address of the block (work with Data32_Sel) │
│ EDI = New Handle of Memory │
│ │
│ Carry = 1 │
│ Invalid handle │
│ Not Enough Memory │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Resize_Memory_Handle
mov edi,[Memory_Handle]
Int_EOS
jc Invalid_Handle
mov [Memory_Handle],edi
mov [Addr_Memory],edx
┌──────────────────────────────────────────────────────────────────────────┐
│Allocate Selector Create a new selector (Data type) │
│ │
│In : │
│ AH = Allocate_Selector │
│ ESI = Physical base address of the new selector │
│ EDI = Size of the new selector modulo 4096 │
│ │
│Out : │
│ Carry = 0 │
│ All Done │
│ BX = New selector │
│ │
│ Carry = 1 │
│ Can't create selector │
│ │
│Other Registers Change : EAX │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Allocate_Selector
mov esi,0a0000h
mov edi,0fh ; 64ko (0000-ffff)
Int_EOS
jc No_Free Selector
mov [_0a0000h_Sel],bx
┌──────────────────────────────────────────────────────────────────────────┐
│DeAllocate Selector Free a Selector │
│ │
│In : │
│ AH = DeAllocate_Selector │
│ BX = Selector │
│ │
│Out : │
│ Carry = 0 │
│ All Done │
│ │
│ Carry = 1 │
│ Can't deallocate selector │
│ │
│Other Registers Change : EAX,EBX │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,DeAllocate_Selector
mov bx,[_0a0000h_Sel]
Int_EOS
jc Invalid_Selector
┌──────────────────────────────────────────────────────────────────────────┐
│Physical Address Mapping Allocate memory mapping │
│ │
│In : │
│ AH = Physical_Address_Mapping │
│ ECX = Size Of region │
│ ESI = Physical address of memory │
│ │
│Out : │
│ Carry = 0 │
│ ESI = Linear Address of the region │
│ All Done │
│ │
│ Carry = 1 │
│ No Room free │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Physical_Address_Mapping
mov ecx,1024*1024
mov esi,[Vesa_Linear_Address]
Int_EOS
jc Not_Enough_Memory
EndIf
┌──────────────────────────────────────────────────────────────────────────┐
│Free Physical Address Mapping Free the allocate memory mapping │
│ │
│In : │
│ AH = Free_Address_Mapping │
│ ESI = Address of the block to free │
│ │
│Out : │
│ Carry = 0 │
│ All Done │
│ │
│ Carry = 1 │
│ Invalid address │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Free_Physical_Address_Mapping
mov esi,[Vesa_Linear_Address]
Int_EOS
jc Invalid_Address
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ La gestion de fichiers ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Charger un fichier en mémoire n'est guère plus compliqué.
Chargement d'un fichier externe :
mov ah,Load_External_File
mov edx,offset File_name
Int_EOS
jc Error_File
mov File_Buffer,eax
Chargement d'un fichier linké avec LightLink (Linker fournit avec
l'E.O.S) :
mov ah,Load_Internal_File
mov edx,offset File_name
Int_EOS
mov File_Buffer,eax
Restitution de la dernière allocation :
mov ah,DeAllocate_Memory
Int_EOS
Chargement d'un fichier externe avec un handle:
mov ah,Load_External_File_Handle
mov edx,offset File_name
Int_EOS
jc Error_File
mov File_Buffer,eax
mov Memory_Handle,edi
Restitution par handle :
mov ah,DeAllocate_Memory_Handle
mov edi,[Memory_Handle]
Int_EOS
jc Invalid_Handle
La fonction Load_Internal_File fonctionne aussi si le programme n'est pas
linké. L'E.O.S est capable de distinguer les deux cas ce qui permet de
développer et tester un programme sans avoir à linker les données.
De plus, si votre fichier est compacté avec un format de type LZ comme
Diet 1.44 l'E.O.S le décompresse automatiquement !
Il est aussi possible de faire l'opération inverse :
mov ah,Write_External_File
mov edx,O File_name
mov esi,[Buffer]
mov ecx,[Size_Buffer]
Int_EOS
jc Error_File
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les fonctions pour la gestion de fichiers ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
┌─────────────────────────┐
│Load Internal File │
│Load External File │
│Load Internal File Handle│
│Load External File Handle│
│Write External File │
└─────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│Load Internal file Load a file which is link with LLINK │
│ if the file is not present the program stop and │
│ display a error message │
│ │
│In : │
│ AH = Load_Internal_File │
│ EDX = Offset of file name │
│ │
│Out : │
│ EAX = Logical address of buffer (work with Data32_Sel) │
│ ECX = Number of bytes read │
│ ESI = Physical address of buffer (work with Flat_Data_Sel) │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Load_Internal_File
mov edx,O File_name
Int_EOS
mov [File_Buffer],eax
┌──────────────────────────────────────────────────────────────────────────┐
│Load External file Load a external file and uncompress it if it has │
│ been compress with Diet 1.44 │
│ │
│In : │
│ AH = Load_External_File │
│ EDX = Offset of file name │
│ │
│Out : │
│ Carry = 0 │
│ All done │
│ EAX = Logical address of buffer (work with Data32_Sel) │
│ ECX = Number of bytes read │
│ ESI = Physical address of buffer (work with Flat_Data_Sel) │
│ │
│ │
│ Carry = 1 │
│ Error │
│ EAX = 1 File Not Found │
│ 2 Not Enough Memory │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Load_External_File
mov edx,O File_name
Int_EOS
jc Error_File
mov [File_Buffer],eax
┌──────────────────────────────────────────────────────────────────────────┐
│Load Internal File Handle Load a file which is link with LLINK │
│ if the file is not present the program stop │
│ and display a error message │
│ │
│In : │
│ AH = Load_Internal_File_Handle │
│ EDX = Offset of file name │
│ │
│Out : │
│ EAX = Logical address of buffer (work with Data32_Sel) │
│ ECX = Number of bytes read │
│ ESI = Physical address of buffer (work with Flat_Data_Sel) │
│ EDI = Handle of Memory │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Load_Internal_File_Handle
mov edx,O File_name
Int_EOS
mov [File_Buffer],eax
mov [Memory_Handle],edi
┌──────────────────────────────────────────────────────────────────────────┐
│Load External File Handle Load a external file and uncompress it if it │
│ has been compress with Diet 1.44 │
│ │
│In : │
│ AH = Load_External_File_Handle │
│ EDX = Offset of file name │
│ │
│Out : │
│ Carry = 0 │
│ All done │
│ EAX = Logical address of buffer (work with Data32_Sel) │
│ ECX = Number of bytes read │
│ ESI = Physical address of buffer (work with Flat_Data_Sel) │
│ EDI = Handle of Memory │
│ │
│ │
│ Carry = 1 │
│ Error │
│ EAX = 1 File Not Found │
│ 2 Not Enough Memory │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Load_External_File_Handle
mov edx,O File_name
Int_EOS
jc Error_File
mov [File_Buffer],eax
mov [Memory_Handle],edi
┌──────────────────────────────────────────────────────────────────────────┐
│Write External File Save a File on a Disk │
│ │
│Entree : │
│ AH = Write_External_File │
│ ECX = Size Of File │
│ EDX = Offset of file name │
│ ESI = Buffer address │
│ │
│Sortie : │
│ Carry = 0 │
│ Tout Va Bien │
│ │
│ Carry = 1 │
│ Erreur Can't write file │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Write_External_File
mov edx,O File_name
mov esi,[Buffer]
mov ecx,[Size_Buffer]
Int_EOS
jc Error_File
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ La gestion des cartes sonores ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
La gestion des cartes sonores n'a pas été oubliée.
L'E.O.S est en effet capable de jouer un sample ou un module Amiga (de 2 à 32
voix) sans la moindre programmation de votre part sur les neuf cartes
suivantes :
■ Sound Blaster
■ Sound Blaster Pro
■ Sound Blaster 16 Asp
■ Sound Blaster AW32
■ Gravis Ultrasound
■ Gravis Ultrasound Max
■ Gravis Ultrasound Ace
■ Gravis Ultrasound Pnp
■ Windows Sound System
Pour une qualité de mixage optimale, l'E.O.S choisit automatiquement le
mixage adapté à la carte sonore détectée (8bits pour la SB pro, 16 bits pour
la Sb 16, etc...).
Attention : La détection est réalisée à l'aide de la variable d'environnement
(Blaster ou Ultrasnd). Si cette variable n'est pas correctement renseignée
aucune carte sonore ne sera détectée.
Exemple :
mov ah,Detect_Sound_Card
xor bx,bx
mov cx,1
Int_EOS
Vous n'êtes pas obligé d'utiliser la détection automatique :
mov ah,Manual_Setup
mov al,Gravis
mov bx,220h
mov cl,7
mov ch,7
mov dl,1
mov dh,1
Int_EOS
Après avoir détecter une carte il faut charger un fichier de
musique en mémoire :
mov ah,Load_Module
mov al,4
mov ebx,22000
mov edx,offset Module_name
xor ecx,ecx
Int_EOS
jc error_file
Pour finir il faut lancer la musique :
mov ah,Play_Module
Int_EOS
Plusieurs fonctions sont alors disponibles :
Set Volume Pour changer le volume de la musique
Play Sample Pour jouer un sample
Get Info Pour obtenir des infos sur la musique
(synchronisation par exemple)
Set Pattern Pour changer de position dans un module
call Pause
mov ax,4c00h
int 21h
Comme vous le voyez ci-dessus, vous n'êtes pas obligé d'arrêter la musique
ou de libérer la mémoire avant de quitter votre programme. C'est l'E.O.S qui
s'en charge. A chaque fois qu'il rencontre la fonction 4c00h ou lors
d'un plantage programme, l'E.O.S restitue automatiquement
l'environnement de départ :
■ Le mode vidéo y compris les modes VESA (132x60,etc...)
■ L'heure de l'horloge.
■ Les interruptions.
■ La mémoire allouée.
■ Stoppe la musique.
Bien entendu, il est toujours possible de libérer la mémoire et d'arrêter
un module pour en charger un autre comme ci-dessous:
mov ah,Stop_Module
Int_EOS
mov ah,Clear_Module
Int_EOS
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Comment accéder aux différentes variables d'un module ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Pour accéder aux informations d'un module, vous pouvez utiliser la fonction
Get_Info ou accéder directement aux variables ci-dessous :
Sound_Card_Type : Byte
Sound_Card_Port : Word
Sound_Card_Irq : Byte
Sound_Card_Dma : Byte
Master_Volume : Byte
Master_Volume_Sfx : Byte
Current_Pattern : Byte
Current_Note : Byte
Current_Speed : Byte
Current_BPM : Byte
Index_Pattern_Order : Dword
Pattern_Order : Byte
Number_Channel : Dword
Diamond_Channel : MS
MS struc
Current_Sample dd 0
Porta dw ?
Tremelo db ?
Current_Position dd ?
Current_Low_Position dd ?
Jump_0e6 db ?
Compt_jump_0e6 db ?
Flags_0e6 db ?
Porta_Freq dw ?
Porta_To dw ?
Vibrato db ?
Vibrato_Flag db ?
FineTune dw ?
Last_Effect dd 0
Voice db ?
Sample_volume db ?
Base_Sample_Volume db ?
Mute db ?
Frequence dw ?
Compt_Frequence dd ?
New_sample db ?
Arp dw ?,?,?
Arp_Counter dw ?
Slide_volume dw ?
Panning db ?
Retrig_Note db ?
Retrig_Note_Val db ?
Cut_Note db ?
Delay_Note db ?
db 0
Delay_Note_Offset dd ?
Addr_Read_Again dd ?
MS ends
Exemple :
mov [Master_Volume],32 ; Set Music Volume
mov [Master_Volume_Sfx],63 ; Set Sample Volume
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Absence de carte sonore ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
L'E.O.S permet de jouer un module même en cas d'absence de carte
sonore. De ce fait, si certains évenements sont synchronisés par rapport à
la musique aucunes modifications n'est a apporter pour les machines sans
carte sonore.
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les déclarations du player de module ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
No_Card = 0
Sb_10 = 01h
Sb_15 = 02h
Sb_20 = 03h
Sb_Pro = 04h
Sb_16 = 05h
Sb_Awe = 06h
Gravis = 10h
Gravis_Max = 11h
Gravis_Ace = 12h
Gravis_Pnp = 13h
WSS = 20h
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les effets sonores ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
L'E.O.S est en mesure de jouer des samples indépendamment de la musique.
Pour cela il faut déclarer des pistes fictives lorsque l'on charge un module
en mémoire :
Exemple :
mov ah,Load_Module
mov al,4+1
mov bx,22000
mov ecx,1 ; Nombre de pistes pour les effets sonores
mov edx,O Module_Name
Int_EOS
jc Error_Loading_Module
On peut ensuite jouer un sample à l'instant voulu très facilement :
mov ah,Play_Sample
mov cx,339 ; Freq.
mov dx,00 ; Piste 1
mov bx,09h ; Sample number
Int_EOS
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les fonctions pour jouer une musique ou des effets sonores ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
┌─────────────────┐
│Detect Sound Card│
│Manual Setup │
│Load Module │
│Play Module │
│Stop Module │
│Clear Module │
│Set Volume │
│Play Sample │
│Get Info │
│Set Pattern │
└─────────────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│Detect Sound Card Detect with the environment variable the sound │
│ card installed │
│ │
│In : │
│ AH = Detect_Sound_Card │
│ CX = 1 Display result of Searching │
│ │
│Out : │
│ AX = 0 No_Card │
│ = 1 Sound Blaster 1.0 │
│ = 2 Sound Blaster 1.5 │
│ = 3 Sound Blaster 2.0 │
│ = 4 Sound Blaster Pro │
│ = 5 Sound Blaster 16 │
│ = 6 Sound Blaster Awe 32 │
│ = 10h Gus │
│ = 11h Gus Max │
│ = 12h Gus Ace │
│ = 13h Gus Pnp │
│ = 20h Windows Sound System │
│ BX = Port │
│ CX = Irq │
│ DX = Dma │
│ SI = Dsp Version (For Sb) ou │
│ Size of RAM of the Gravis │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Detect_Sound_Card
mov cx,1
Int_EOS
┌──────────────────────────────────────────────────────────────────────────┐
│Manual Setup │
│ │
│In : │
│ AH = Manual_Setup │
│ AL = Type │
│ BX = Port │
│ CL = Irq1 │
│ CH = Irq2 ; Irq Gus 2 │
│ DL = Dma1 ; Dma Gus 1 or Dma 8 Bits for SB │
│ DH = Dma2 ; Dma Gus 2 or Dma 16 Bits for SB │
│ │
│Out : │
│ Carry Off │
│ Init Ok │
│ │
│ Carry On │
│ No Sound Card Found │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Manual_Setup = 37h
If Impossible
mov ah,Manual_Setup
mov al,Gravis
mov bx,220h
mov cl,7
mov ch,7
mov dl,1
mov dh,1
Int_EOS
...
mov ah,Manual_Setup
mov al,Sb_16
mov bx,220h
mov cl,7
mov dl,1
mov dh,5
Int_EOS
EndIf
┌──────────────────────────────────────────────────────────────────────────┐
│Load Module Load a module & initialize into the memory │
│ │
│In : │
│ AH = Load_Module │
│ AL = Bit 0 = 1 Load a internal module (can be compress and link │
│ with LLINK) │
│ = Bit 1 = 1 Load module from memory │
│ = Bit 2 = 1 Force old mod Loading (15 instr) │
│ BX = Replay rate (16000 to 44100 Hz) │
│ CX = Number of Sfx Channel │
│ DS:EDX = Offset of Module name or │
│ Offset into the memory of the beginning of the module │
│ │
│Out : │
│ Carry = 0 │
│ All Done │
│ │
│ Carry = 1 │
│ Can't Load Module │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Load_Module
mov al,4+1
mov bx,22000
xor ecx,ecx
mov edx,O Module_Name
Int_EOS
jc Error_Loading_Module
┌──────────────────────────────────────────────────────────────────────────┐
│Play Module Start playing the module │
│ │
│In : │
│ AH = Play_Module │
│ │
│Out : │
│ Carry = 0 │
│ All Done │
│ │
│ Carry = 1 │
│ Can't Play Module │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Play_Module
Int_EOS
┌──────────────────────────────────────────────────────────────────────────┐
│Stop Module Stop playing module │
│ │
│In : │
│ AH = Stop_Module │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Stop_Module
Int_EOS
┌──────────────────────────────────────────────────────────────────────────┐
│Clear Module Unload the module from memory │
│ │
│In : │
│ AH = Clear_Module │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Clear_Module
Int_EOS
┌──────────────────────────────────────────────────────────────────────────┐
│Set Volume Set the master volume of the module │
│ │
│In : │
│ AH = Set_Volume │
│ CL = Volume (0 to 63) │
│ DL = Sfx Volume (0 to 63) │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Set_Volume
mov cl,[New_Volume]
mov dl,[New_Volume_Sfx]
Int_EOS
┌──────────────────────────────────────────────────────────────────────────┐
│Play Sample Play a sample include into the module │
│ │
│In : │
│ AH = Play_Sample │
│ BX = Sample numbers │
│ CX = Sample Frequency │
│ DX = voice of sample │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Play_Sample
mov bx,10
mov cx,15fh
mov dx,4
Int_EOS
┌──────────────────────────────────────────────────────────────────────────┐
│Get Info Get information about the module when playing │
│ │
│In: │
│ AH = Get_Info │
│ │
│Out: │
│ AH = Position │
│ AL = Pattern │
│ BX = Note │
│ CL = Master Volume │
│ DL = Master Volume Sfx │
│ │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Get_Info
Int_EOS
┌──────────────────────────────────────────────────────────────────────────┐
│Set Pattern Set the current position of the playing module │
│ │
│In: │
│ AH = Set_Pattern │
│ BX = New_Position │
│ CX = New_Note │
│ │
│Out: │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Set_Pattern
mov bx,[New_Position]
mov cx,[New_Note]
Int_EOS
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Gestion d'un second écran monochrome ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Pour faciliter le debuggage de vos programmes, l'E.O.S fournit des
fonctions qui permettent de controler un deuxième écran via une carte
monochrome de type Hercule.
L'E.O.S détecte automatiquement votre écran. Cependant, si celui-ci n'était
pas reconnu, vous pouvez utiliser la séquence suivante :
mov ah,Set_Mono
mov bx,On
Int_EOS
Deux fonctions sont alors disponibles : l'affichage d'une chaîne de
caractère ASCII et l'affichage d'une valeur Hexadécimal.
Afficher une Chaîne ASCII :
mov ah,Set_String_Mono
mov bx,Coordonee X
mov cx,Coordonee Y
mov edx,Offset Chaine_A_Afficher
Int_EOS
Afficher une Valeur Hexadécimal :
mov ah,Set_Value_Mono
mov bx,Coordonee X
mov cx,Coordonee Y
mov edx,Valeur_A_Afficher
Int_EOS
Une macro est également disponible : Send qui permet une utilisation
plus simple de la fonction Set_Value_Mono
Afficher une Valeur sur l'écran monochrome :
Send Valeur_A_Afficher,X,Y
La chaîne ASCII peut se terminer soit par $ soit par le caractère NULL.
La fonction prend aussi en compte les caractères retour chariot (13 et 10).
Les valeurs en hexadécimal ne doivent pas dépasser 32 Bits.
Attention : Pour un gain de temps aucun test n'est effectué au niveau des
coordonnées de l'écran.
Note : L'écran Monochrome est automatiquement effacé au début et a la fin d'un
programme.
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les fonctions pour utiliser un second écran pour le debuggage ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
┌───────────────┐
│Set Mono │
│Set String Mono│
│Set Value Mono │
└───────────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│Set Mono Force On/Off the display of all the Monochrome Function │
│ │
│In : │
│ AH = Set_Mono │
│ BX = On Force Monochrome Off │
│ Off Force Monochrome On │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Set_Mono
mov bx,On
Int_EOS
┌──────────────────────────────────────────────────────────────────────────┐
│Set String Mono Display a string on the Monochrome adapter │
│ │
│In : │
│ AH = Set_String_Mono │
│ BX = Coordonate X │
│ CX = Coordonate Y │
│ EDX = Address of text ending by $ │
│ │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Set_String_Mono
mov bx,1
mov cx,10
mov edx,offset text_mono
Int_EOS
┌──────────────────────────────────────────────────────────────────────────┐
│Set Value Mono Display A Word in Hexadécimal on the Monochrome adapter │
│ │
│In : │
│ AH = Set_Value_Mono │
│ BX = Coordonate X │
│ CX = Coordonate Y │
│ EDX = Value to be display │
│ │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Set_Value_Mono
mov bx,1
mov cx,10
mov dx,1234h
Int_EOS
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Le clavier ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Une gestion clavier très simple à été implantée dans l'E.O.S afin de vous
faciliter la vie. Pour l'activer il faut prendre le contrôle de l'interruption
09 comme ci-dessous :
Activation du gestionnaire de clavier
mov ah,Use_Int_09
mov bx,On
Int_EOS
Le clavier est alors entièrement gérer par l'E.O.S qui dialogue directement
avec lui. Il n'y a plus aucun appel vers les anciens gestionnaires du
DOS. L'interruption 16h ne fonctionne donc plus.
La lecture du clavier devient alors très facile grâce à la variable Key_Map.
Cette variable est en réalité un tableau de 128 octets qui correspond
au 128 scancodes renvoyés par le clavier.
Pour connaître l'état d'une touche il suffit de savoir si sont scancode et
à 0 ou 1 (On ou Off).
Exemple, pour tester si la touche Escape est actuellement enfoncée :
cmp Key_Map[Escape],On
je Touche_Escape_Enfoncé
...
Touche_Escape_Enfoncé:
mov Key_Map[Escape],Off
Un scancode spécial "All" est utilisé pour savoir une touche a été enfoncée
puis relâchée.
Exemple, pour tester si la touche Escape à été enfoncée :
cmp Key_Map[All],Escape
je Touche_Escape_Enfoncer
Ce qui permet d'attendre une touche quelconque :
@@Attend_Touche:
cmp Key_Map[All],Off
je @@Attend_Touche
mov Key_Map[All],Off
Il est bien entendu possible de désactiver le clavier et de revenir à l'ancien
gestionnaire.
Restauration du clavier :
mov ah,Use_Int_09
mov bx,Off
Int_EOS
Note : A la fin du programme, l'E.O.S restitue toutes les interruptions la
restauration de l'interruption 09 n'est donc pas obligatoire.
┌──────────────────────────────────────────────────────────────────────────┐
│Use Int 09 Use Internal Keyboard handler to use keyboard │
│ │
│In : │
│ AH = Use_Int_09 │
│ BX = On Enable Int 09 │
│ = Off Disable Int 09 (Default setting) │
│ │
│ │
│Out : │
│ │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Use_Int_09
mov bx,On
Int_EOS
...
@@Pause: ; Test if key pressed
cmp Key_Map[All],Off
je @@Pause
mov Key_Map[All],Off
...
@@Pause: ; Test if the Esc key is pressed
cmp Key_Map[Escape],On ; Actually
jne @@Pause
...
@@Pause: ; Test if the ESC key have been pressed
cmp Key_Map[All],Escape
jne @@Pause
──────────────────────────────────────────────────────────────────────────────
Les déclarations pour Key_Map (Azerty)
──────────────────────────────────────────────────────────────────────────────
All
Escape
Return
Alt
Space
Left
Right
Up
Down
Plus
Moins
Ctrl
Num_0 à Num_9
Key_0 à Key_9
Key_A à Key_Z
Key_F1 à Key_F12
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Synchronisation avec le balayage ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
L'E.O.S possède son propre système de synchronisation.
Contrôle du retracage de l'écran :
mov ah,Wait_Vbl
Int_EOS
L'utilisation de l'interruption 08 ou timer permet d'augmenter les capacités
de cette fonction. Comme pour l'interruption clavier il n'y a pas d'appel vers
les anciens gestionnaires.
Activation du gestionnaire de synchronisation :
mov ah,Use_Int_08
mov bx,On
Int_EOS
Attention : Lorsque vous utilisez Diamond, la fonction Use_Int_08 est
automatiquement activée. Dans ce cas la, Use_Int_08 ne sert à rien.
En retour, Wait_Vbl renvoie alors le nombre de balayage effectué depuis le
dernier appel. Cette fonction renvoie toujours 1 si l'interruption 08 est Off.
mov ah,Wait_Vbl
Int_EOS
mov [Nbs_Vbl],eax
Grâce à l'utilisation de cette interruption et à la fonction Wait_Vbl votre
programme est toujours capable de savoir combien de frame il a perdu. On
dispose ainsi d'un compteur régulier très pratique pour le calcul des
déplacements.
La fonction, Change_Synchro_Int_08 permet de changer la fréquence de balayage
pour le timer qui est de 70hz par défaut :
mov bx,60 ; 60Hz
mov ah,Change_Synchro_Int_08
Int_EOS
Une macro est aussi disponible : Colors qui permet de changer une couleur
temporairement pour décomposer chaque routine de votre programme.
Fonction Colors:
colors Numero_de_couleur,Valeur_Rouge,Valeur_Verte,Valeur_bleue
Exemple d'utilisation des fonctions de balayage :
@@Boucle:
colors 0,63,0,0 ; Première couleur en Rouge vif
call Procedure_1
colors 0,0,63,0 ; Deuxième couleur en Ver Vif
call Procedure_2
mov ah,Wait_Vbl
Int_EOS
@@Compt:
add [Valeur_Reguliere],1
dec eax ; On additionne des valeurs régulières
jne @@Compt
cmp [Key_Map+All],On
jne @@Boucle
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les fonctions de synchronisations ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
┌─────────────────────┐
│Wait Vbl │
│Use Int 08 │
│Change Synchro Int 08│
└─────────────────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│Wait Vbl Wait the vertical retrace │
│ │
│In : │
│ │
│Out : │
│ EAX = Number of Vbl lost since the last call │
│ (work only when the Int 08 is on) │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Wait_Vbl
Int_EOS
┌──────────────────────────────────────────────────────────────────────────┐
│Use Int 08 Use Int 08 (IRQ 0) to count frame rate and have a stable │
│ vertical retrace │
│ Defaults frequency is 70Hz │
│ │
│In : │
│ AH = Use_Int_08 │
│ BX = On Enable Int 08 │
│ = Off Disable Int 08 │
│ │
│ │
│Out : │
│ │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Use_Int_08
mov bx,On
Int_EOS
┌──────────────────────────────────────────────────────────────────────────┐
│Change Synchro Int 08 Change frequency for Interupt 08 │
│ Defaults frequency is 70Hz │
│ │
│In : │
│ BX = frequency │
│ AH = Change_Synchro_Int_08 │
│ │
│Out : │
│ │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov bx,70 ; 70hz
mov ah,Change_Synchro_Int_08
Int_EOS
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les variables ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
L'E.O.S possède quelques variables 'global' qui peuvent être nécessaires à
tout moment lors de l'exécution d'un programme :
───────────────────────────────────────────────────────────────────────────────
Code32_Sel
───────────────────────────────────────────────────────────────────────────────
Sélecteur de code (CS).
Exemple : Détourner l'interruption 70h :
mov ah,Set_Int
mov bx,70h
mov cx,[Code32_Sel] ; Sélecteur
mov edx,O New_Int_70h ; Offset de la nouvelle routine
Int_EOS
Attention ! En mode protégé, il est interdit de faire :
mov cs:[Valeur],10
Cela déclencherait une exception et arrêterait votre programme.
───────────────────────────────────────────────────────────────────────────────
Data32_Sel
───────────────────────────────────────────────────────────────────────────────
Sélecteur de Données (DS).
Exemple d'utilisation de Data32_Sel :
Valeur dd 0
mov [Valeur],10
En fait, les sélecteurs Code32_Sel et Data32_Sel sont identiques.
La différence porte sur leur accès. Code32_Sel est en lecture alors
que Data32_Sel est en lecture et écriture.
Au début d'un programme tous les sélecteurs (sauf CS) sont initialisés avec la
valeur de Data32_Sel.
Attention : Sous WATCOM, le sélecteur ES pointe sur le PSP du programme.
───────────────────────────────────────────────────────────────────────────────
Flat_Data_Sel, Flat_Code_Sel
───────────────────────────────────────────────────────────────────────────────
Sélecteurs qui ont pour origine l'adresse zéro de la mémoire. Très utile pour
lire les variables du BIOS. Flat_Data_Sel est en lecture et écriture mais il
ne peut pas être utilisé pour exécuter du code tandis que Flat_Code_Sel est en
lecture seulement mais peut être utilisé pour exécuter du code.
Lire le mode vidéo courant :
push es
mov es,cs:[Flat_Code_Sel]
mov al,es:[449h] ; 40h:49h en mode réel
pop es
───────────────────────────────────────────────────────────────────────────────
Sélecteur 40h
───────────────────────────────────────────────────────────────────────────────
Sélecteurs qui permet d'accéder directement aux variables du BIOS :
Lire le mode vidéo courant :
push es
mov ax,40h
mov es,ax
mov al,es:[49h] ; 40h:49h en mode réel
pop es
───────────────────────────────────────────────────────────────────────────────
Real_DS,Real_ES,Real_FS,Real_GS,Real_SS,Real_SP
───────────────────────────────────────────────────────────────────────────────
Ces variables contiennent les futures valeurs des différents segments lors d'un
appel en mode réel (Voir Le mode Réel).
───────────────────────────────────────────────────────────────────────────────
_0b0000h, _0b8000h, _0a0000h
───────────────────────────────────────────────────────────────────────────────
Ces variables contiennent les différentes adresses 32 bits de la VRAM.
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les Macros ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
L'E.O.S possède des macros qui permettent de simplifier la programmation.
───────────────────────────────────────────────────────────────────────────────
Macro Colors
───────────────────────────────────────────────────────────────────────────────
colors Numéro_de_couleur,Valeur_Rouge,Valeur_Verte,Valeur_bleu
(Voir Synchronisation avec le balayage)
───────────────────────────────────────────────────────────────────────────────
Macro Get_Param
───────────────────────────────────────────────────────────────────────────────
Get_Param Param_Buffer
...
Param_Buffer db 128 dup (0)
Renvoie dans Param_Buffer les paramètres de la ligne de commande.
───────────────────────────────────────────────────────────────────────────────
Macro Send
───────────────────────────────────────────────────────────────────────────────
Send Valeur_A_Afficher,X,Y
(Voir Gestion d'un second écran monochrome)
───────────────────────────────────────────────────────────────────────────────
Macro DosInt
───────────────────────────────────────────────────────────────────────────────
DosInt Numéro_d_interruption
(Voir Le mode réel)
───────────────────────────────────────────────────────────────────────────────
Macro DosCall
───────────────────────────────────────────────────────────────────────────────
DosCall Adresse_Mode_réel
(Voir Le mode réel)
───────────────────────────────────────────────────────────────────────────────
Macro Init_es_di
───────────────────────────────────────────────────────────────────────────────
Init_es_di Offset adresse_32_bits
(Voir Le mode réel)
───────────────────────────────────────────────────────────────────────────────
Macro Init_ds_dx
───────────────────────────────────────────────────────────────────────────────
Init_ds_dx Offset adresse_32_bits
(Voir Le mode réel)
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Le mode réel ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Le mode réel est accessible à partir de l'E.O.S à l'aide de quatre macros et
de six variables :
DosInt macro Int_Number
DosCALL macro _Seg_,_Ofs_
Init_es_di macro Adrs
Init_ds_dx macro Adrs
Real_GS :dword
Real_FS :dword
Real_DS :dword
Real_ES :dword
Real_SS :dword
Real_SP :dword
En mode protégé, il n'y a plus de registres de segments mais des sélecteurs.
Les variables Real_xx contiennent par conséquent les valeurs des différents
segments lors d'un appel en mode réel. Si une interruption du DOS à besoin de
retourner un paramètre dans ES, celui-ci est retourné dans Real_ES. Real_ES
correspond donc au registre de segment ES du mode réel.
Pour appeler une interruption (Int) du mode réel :
DosInt Numéro_d_interruption
Exemple :
mov ax,13h ; Mode 320x200 256 Couleurs
DosInt 10h ; Appel de la fonction BIOS
; Set Video Mode
Pour appeler une fonction (Call) en mode réel :
DosCall Adresse_Mode_réel
Exemple :
XMS_Adresse dw 0,0
mov ax,4300h ; Fonction qui teste si un
DosInt 2fh ; Driver XMS est présent
cmp al,80h
je No_XMS_Driver
mov ax,4310h ; Si oui demande son point
DosInt 2fh ; d'entré
mov [XMS_Adresse],bx
mov eax,[Real_ES]
mov [XMS_Adresse+2],ax
xor ah,ah ; Fonction 0 du driver XMS
DosCall Dword Ptr [XMS_Adresse] ; Get XMS Version
Pour initialiser les variables qui seront utilisées en mode réel :
Init_es_di Adresse_32bits
Init_ds_dx Adresse_32bits
Exemple :
Vesa_Buffer db 256 dup (0)
Init_es_di Vesa_Buffer
mov ax,4f00h ; Teste la présence d'un
DosInt 10h ; Driver VESA
cmp dword ptr Vesa_Buffer,'ASEV'
jne no_vesa
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les interruptions ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
L'E.O.S permet de modifier les interruptions grâce aux fonctions Get_Int et
Set_Int.
Exemple : Détourner l'interruption 70h :
mov ah,Get_Int ; Lit L'ancien vecteur
mov bx,70h
Int_EOS
mov [Old_Selector_Int_70h],cx
mov [Old_Offset_Int_70h],edx
mov ah,Set_Int
mov bx,70h
mov cx,[Code32_Sel] ; Sélecteur
mov edx,O New_Int_70h ; Offset de la nouvelle routine
Int_EOS
L'E.O.S met aussi à la disposition du programmeur toute une série de fonctions
accessibles via l'interruption 21h.
Exemple : Afficher un message :
Msg db 'Hello Word',13,10,36
mov ah,9 ; Fonction Display String
mov edx,Offset Msg
int 21h
mov ax,4c00h
int 21h
Attention ! Pour terminer un programme il faut IMPERATIVEMENT appeler la
fonction 4ch de l'interruption 21h
Tous les appels à des interruptions à partir du mode protégé sont
automatiquement transférés en mode réel :
xor ax,ax
int 33h
est équivalent à :
xor ax,ax
DosInt 33h
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les IRQ ou interruptions matérielles ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Toutes les IRQs sont accessibles dans votre programme. Par contre L'E.O.S a
reprogammé ses interruptions pour éviter des conflits avec les exceptions du
mode protégé. Pour utiliser une IRQ l'E.O.S met deux fonctions à la
disposition du programmeur :
Get_IRQ :
Fonction qui renvoie l'adresse d'une IRQ.
Set_IRQ :
Fonction qui détourne une IRQ.
Exemple d'utilisation :
Old_IRQ0 Label Fword
Old_Offset_IRQ0 dd 0
Old_Selector_IRQ0 dw 0
mov ah,Get_IRQ
mov bl,0 ; IRQ timer
Int_EOS
mov [Old_Selector_IRQ0],cx
mov [Old_Offset_IRQ0],edx
mov ah,Set_IRQ
mov bl,0 ; IRQ timer
mov cx,cs
mov edx,Offset New_IRQ0
Int_EOS
...
New_IRQ0:
...
jmp fword ptr cs:[Old_IRQ0]
Vous pouvez également utiliser les fonctions du mode réel :
mov ax,2508h ; Détourner l'IRQ timer via Dos
init_ds_dx,Mon_Programme
int 21h
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les Exceptions ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
───────────────────────────────────────────────────────────────────────────────
Différence entre une exception et une intèrruption
───────────────────────────────────────────────────────────────────────────────
Une exception est une interruption qui a la falculté de se déclencher à l'
intérieur d'une instruction. Par exemple :
mov ecx,-1
rep movsb ; Une interruption doit attendre la fin du rep movsb
pour être prise en compte.
───────────────────────────────────────────────────────────────────────────────
En cas de plantage
───────────────────────────────────────────────────────────────────────────────
Toutes les exceptions sont gérées par l'E.O.S.
Lorsque l'une d'elle se déclenche, l'E.O.S arrête votre programme et restitue
automatiquement la mémoire allouée et le mode vidéo de départ.
───────────────────────────────────────────────────────────────────────────────
Comment détourner une exception sous E.O.S.
───────────────────────────────────────────────────────────────────────────────
Les exceptions sont gérées comme en DPMI. Elles possèdent une stucture en
entrée et un retf en sortie (voir doc du DPMI).
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les fonctions pour gérer les interruptions ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
┌───────┐
│Get Int│
│Set Int│
│Get Irq│
│Set Irq│
└───────┘
┌──────────────────────────────────────────────────────────────────────────┐
│Get_Int Get protected mode interrupt vector │
│ │
│In : │
│ AH = Get_Int │
│ BX = Interrupt number │
│ │
│Out : │
│ CX:EDX = Selector:Offset of interrupt │
│ │
│Autre Registre Modifie : Aucun │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Get_Int
mov bx,10h
Int_EOS
mov [Old_Int_10_Selector],cx
mov [Old_Int_10_Offset],edx
┌──────────────────────────────────────────────────────────────────────────┐
│Set_Int Set protected mode interrupt vector │
│ │
│In : │
│ AH = Get_Int │
│ BX = Interrupt number │
│ CX:EDX = Selector:Offset of interrupt │
│ │
│Out : │
│ │
│Autre Registre Modifie : Aucun │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Set_Int
mov bx,10h
mov cx,cs
mov edx,O New_Int_10
Int_EOS
┌──────────────────────────────────────────────────────────────────────────┐
│Get_Irq Get protected mode irq vector │
│ │
│In : │
│ AH = Get_Irq │
│ BX = Irq number │
│ │
│Out : │
│ CX:EDX = Selector:Offset of irq │
│ │
│Autre Registre Modifie : Aucun │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Get_Irq
mov bx,1h ; Keyboard
Int_EOS
mov [Old_Irq_01_Selector],cx
mov [Old_Irq_01_Offset],edx
┌──────────────────────────────────────────────────────────────────────────┐
│Set_Irq Set protected mode irq vector │
│ │
│In : │
│ AH = Get_Irq │
│ BX = Irq number │
│ CX:EDX = Selector:Offset of irq │
│ │
│Out : │
│ │
│Autre Registre Modifie : Aucun │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Set_Irq
mov bx,1h ; Keyboard
mov cx,cs
mov edx,O New_Irq_01
Int_EOS
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Le linker ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
L'E.O.S dispose d'un utilitaire (LLINK.EXE) qui permet de créer un seul
fichier exécutable à partir de plusieurs fichiers de données.
programme.exe
image.pcx ----> final.exe
musique.mod
Une fois linké, les fichiers de données sont accessibles très facilement à
l'aide de la fonction Load_internal_File.
Exemple d'utilisation de Load_Internal_File et de Load_External_File :
Fichier_Linker db 'IMAGE.PIC',0
Fichier_Externe db 'PRG.CFG',0
mov ah,Load_Internal_File ; Charge un fichier interne
mov edx,O Fichier_Linker
Int_EOS
Pas d'erreurs possibles car elles sont gérées par l'E.O.S.
mov ah,Load_External_File ; Charge un fichier externe
mov edx,O Fichier_Externe
Int_EOS
jc Error_Loading
Gestion des erreurs par l'utilisateur.
Pour indiquer à LLINK la liste des fichiers à linker il suffit de créer un
fichier de lien comme ci-dessous.
Contenu d'un fichier de lien (prg.eos) :
FINAL.EXE ; Nom de l'exécutable à créer
PRG.EXE ; Nom de l'exécutable à linker
IMAGE.PCX ; Fichier de données à linker
MUSIQUE.MOD ; Fichier de données à linker
:END ; Fin
Linkage :
LLINK prg.eos
Afin de faciliter la programmation, il est possible d'utiliser la fonction
Load_Internal_File avec des fichiers externes, ce qui permet de linker un
programme lorsqu'il est entièrement terminé (Voir Example4).
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Le Debugger 32 bits ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
───────────────────────────────────────────────────────────────────────────────
DEBUG.OBJ
───────────────────────────────────────────────────────────────────────────────
Le debugger DEBUG.OBJ est un fichier objet externe qu'il vous suffit d'inclure
au moment du linkage :
TLINK eos+mon_programme+debug /x /3
Pour l'appeler à partir de votre programme une fonction est mise à votre
disposition : DEBUG. Vous pouvez ainsi activer le debugger à
n'importe quel instant à l'aide d'un simple Call :
Exemple d'appel du debugger sous E.O.S.
Locals
.386
CODE32 SEGMENT PUBLIC PARA 'CODE' USE32
ASSUME CS:CODE32,DS:CODE32,ES:CODE32
INCLUDE ..\RESOURCE\EOS.INC
Msg db ' ■ Hello world...',13,10,36
Start32:
call debug ; Where you want !!! Alt-x to exit
mov ah,9
mov edx,O Msg
int 21h ; Call Display String
mov ax,4c00h
int 21h ; Exit with Error Code 0
CODE32 ENDS
END
Exemple d'appel du debugger sous WATCOM
void main()
{
init_EOS();
debug();
printf(" ■ Hello world...\x0D\x0A");
exit(0);
}
Les fonctions du debugger sont les suivantes :
Pause Break Permet d'appeler le debugger à tout instant
Alt-X Exit Permet de quitter le debugger à tout instant
F1 Mono Le debugger passe sur l'écran monochrome
F2 Color Le debugger passe sur l'écran couleur
F3 Nop Permet de placer des instructions NOP dans la fenêtre
de code
F4 Here Permet d'aller à un point précis du programme
F5 Fpu Remplace la fénètre Dump par les registres du
co-processeur
Alt-F5 UsrScr Affiche l'écran vidéo du programme
F7 Next Pour tracer à l'intérieur des procédures
Alt-F7 Int Pour tracer à l'intérieur des interruptions
F8 Trace Pour tracer sans rentrer dans les procédures
F9 Run Pour rendre la main au programme
F10 BreakPoint Pour placer un point d'arrêt dans la fenêtre code
F11 Origin Pour positionner la fenêtre code sur CS:EIP
F12 About Pour connaître la version du debugger
Alt Toggle Remplace la fenêtre des registres par celle des
sélecteurs
Arrows ScrollDump Scroll la fenêtre Code
Alt Arrows ScrollCode Scroll la fenêtre Dump
Ctrl Arrows DecalCode Décalage du désassemblage
Ctrl N NewEIP Permet de changer CS:EIP
Ctrl D NewDump Permet de changer l'adresse de la fenêtre Dump
Ctrl G Goto Permet d'aller à un point précis du programme
Ctrl H Help Affiche un écran d'aide
A chaque fois que le debugger rencontre une interruption de l'E.O.S, du DOS
ou du DPMI, celui indique en clair la fonction demandée.
Exemple :
mov ah,9h
int 21 = Display String
mov ax,300h
int 31h = Simulate Real Mode Interrupt
mov ah,47h
Int_EOS = Physical Address Mapping
Un utilitaire est aussi fourni pour configurer le debugger : EDCONFIG.EXE.
Pour plus d'infos taper EDCONFIG -h
───────────────────────────────────────────────────────────────────────────────
WDEBUG.EXE
───────────────────────────────────────────────────────────────────────────────
Vous pouvez aussi utiliser WDEBUG pour tracer des programmes au format LE.
Pour cela il faut extraire DOG4GW du programme EXE avec PMWBIND :
PMWBIND /U fichier.EXE
Vous pouvez alors lancer le programme pour le debugger :
WDEBUG fichier.LE
Pour appeler le debugger appuyez simplement sur la touche Pause.
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les fonctions du Debuggeur 32 bits ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
┌───────────┐
│Debug │
│Debug Back │
└───────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│Debug Initialize and call the debugger │
│ │
│ │
│ │
│In : │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
call debug
┌──────────────────────────────────────────────────────────────────────────┐
│Debug_Back Initialize the debugger for Pause-key and Break_Point │
│ │
│ │
│ │
│In : │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
call debug_Back
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Appel du debugger par Break point ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
┌───────────┐
│Break Point│
└───────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│Break_Point call the debugger │
│ │
│ │
│ │
│In : │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
Break_Point
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Restitution automatique de l'environnement de départ ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Vous n'êtes pas obligé de libérer la mémoire avant de quitter votre
programme. A chaque fois qu'il rencontre la fonction 4c00h ou lors d'un
plantage programme, l'E.O.S restitue automatiquement l'environnement de
départ :
■ Le mode vidéo y compris les modes VESA (132x60,etc...)
■ L'heure de l'horloge.
■ Les interruptions.
■ La mémoire allouée.
■ Stoppe la musique.
Il est également possible de restituer à tout moment le mode vidéo de départ...
mov ah,Restore_Video_Mode
Int_EOS
Pour les erreurs, l'E.O.S dispose d'une sortie spécialisée qui permet d'afficher
un message d'erreur :
mov ah,Exit_Error
mov edx,Offset Error_Txt
Int_EOS
Cette fonction est identique à :
mov ah,9 ; Fonction Display String
mov edx,Offset Msg
int 21h
mov ax,4c01h
int 21h
L'E.O.S vous permet également d'écrire directement en Ram vidéo et d'employer
des couleurs avec la fonction Direct_Send :
lea edx,Message
mov ah,Direct_Send
Int_EOS
...
Message db " ",0,1,"■ Color Blue ",0,4,"Red ",13,10,0,0
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les Fonctions système ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
┌──────────────────────────────────────────────────────────────────────────┐
│Exit Error │
│Restore Video Mode │
│Detect Windows │
│Direct Send │
└──────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│Exit Error Restore initial Video mode , interrupts , free all reserved │
│ memory ,stop music if played and exit (with error code 1) │
│ with a error message │
│ │
│In : │
│ AH = Exit_Error │
│ DS:EDX = Offset message to display │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Exit_Error
mov edx,Offset Error_Txt
Int_EOS
┌──────────────────────────────────────────────────────────────────────────┐
│Restore Video Mode Restore the inital video which is be active at the │
│ start of the program │
│ │
│In : │
│ AH = Restore_Video_Mode │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Restore_Video_Mode
Int_EOS
┌──────────────────────────────────────────────────────────────────────────┐
│Detect Windows Detect If Windows is running │
│ │
│In : │
│ AH = Detect_Windows │
│ │
│Out : │
│ AL = Windows version │
│ │
│Other Registers Change : None │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
Windows_3x = 3
Windows_95 = 4
lea edx,Windows_Txt
mov ah,Detect_Windows
Int_EOS
or al,al
jnz Error
...
Windows_Txt db " ■ Sorry, but this program can not run under Microsoft Windows (tm)",13,10,36
┌──────────────────────────────────────────────────────────────────────────┐
│Direct Send Write a text directly to video ram . Color allowed │
│ │
│In : │
│ AH = Direct_Send │
│ EDX = Offset message to Display │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
│Comand : 0,0 = end │
│ 0,1..255 = color │
│ 13 = first colonne │
│ 10 = next ligne │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
Direct_Send = 0Eh
If Impossible
lea edx,Message
mov ah,Direct_Send
Int_EOS
...
Message db " ",0,1,"■ Color Blue ",0,4,"Red ",13,10,0,0
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Comment développer une librairie compatible WATCOM C et E.O.S ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Pour développer une librairie à la fois compatible avec WATCOM et E.O.S, vous
devez créer deux fichiers objets différents comme ci-dessous :
- <Nom>.obj : VESA.OBJ (E.O.S)
- W<Nom>.obj : WVESA.OBJ (WATCOM)
Pour cela, vous pouvez générer une variable de compilation dans
votre fichier makefile, par exemple __Use_Watcom__ :
PRG = VESA
RES = ..\RESOURCE
$(PRG).exe: $(PRG).obj
@Echo $(PRG) Has Been Assembled
$(PRG).obj: $(PRG).asm
@tasm3 $(PRG) $(RES)\$(PRG) /m /q /p /d__Use_Watcom__=0
@tasm3 $(PRG) $(RES)\W$(PRG) /m /q /p /d__Use_Watcom__=1
A partir de cette variable vous pouvez ensuite gérer deux codes
dans votre fichier source :
If __Use_Watom__
... ; CODE Specifique à WATCON
...
Else
... ; CODE Specifique à E.O.S
...
EndIF
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Différences entre un programme E.O.S et WATCOM ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
───────────────────────────────────────────────────────────────────────────────
La gestion mémoire sous WATCOM
───────────────────────────────────────────────────────────────────────────────
Sous WATCOM, la mémoire est de type FLAT et commence à l'adresse 0.
Sous E.O.S, la mémoire est définit selon l'endroit ou le programme à éte
chargé.
Pour allouer de la memoire sous E.O.S :
mov ah,Allocate_Memory_Handle
mov edx,Taille
Int_EOS
mov [Adresse_Memoire],edx
mov [Handle_Memoire],edi
Pour allouer de la memoire sous WATCOM :
mov ah,Allocate_Memory_Handle
mov edx,Taille
Int_EOS
mov [Adresse_Memoire],eax
mov [Handle_Memoire],edi
Example pour utiliser les deux :
mov ah,Allocate_Memory_Handle
mov edx,Taille
Int_EOS
If __Use_Watom__
mov [Adresse_Memoire],eax
Else
mov [Adresse_Memoire],edx
Endif
mov [Handle_Memoire],edi
!!! Idem pour Load_Internal_file et Load_External_File !!!
───────────────────────────────────────────────────────────────────────────────
Les appels aux interruptions en mode REEL
───────────────────────────────────────────────────────────────────────────────
Sous E.O.S :
Init_es_edi Buffer_Vesa
mov ax,4f00h
DosInt 10h
Sous WATCOM :
On ne peut pas adresser directement les variables ni même
utiliser les macros init_DS_DX, car le programme est chargé
au-dessus du premier Mega octets et le DOS ne peut atteindre
ces variables.
Il est donc conseillé d'allouer de la mémoire avec la fonction
48h de l'interruption 21h pour faire la passerelle avec le mode
réel comme ci-dessous :
xor eax,eax
mov ah,48h
mov bx,256/16
int 21h
mov edi,O DPMI_CALL
mov W [edi.Real_mode_Call._EAX],4f00h
mov [edi.Real_mode_Call._EDI],0h
mov [edi.Real_mode_Call._ES],ax
mov ax,300h
mov bl,10h ; Int 10h
xor cx,cx
int 31h ; Simule une interruption
La structure à utiliser pour les appels DPMI est la suivante :
Real_mode_Call STRUC
_EDI dd ?
_ESI dd ?
_EBP dd ?
dd ?
_EBX dd ?
_EDX dd ?
_ECX dd ?
_EAX dd ?
_flags dw ?
_ES dw ?
_DS dw ?
_FS dw ?
_GS dw ?
_IP dw ?
_CS dw ?
_SP dw ?
_SS dw ?
ends
DPMI_CALL Real_mode_Call <>
Pour faciliter la création de programme il serait plus judicieux
d'allouer de la mémoire grâce aux fonctions DOS pour avoir très
peu de différence entre les codes sources
Exemple :
If __Use_Watcom__
mov edi,O DPMI_CALL
mov W [edi.Real_mode_Call._EAX],4800h
mov W [edi.Real_mode_Call._EBX],512/16
mov ax,300h
mov bl,10h
xor cx,cx
int 31h
jc Error_vesa
mov edi,O DPMI_CALL
movzx eax,W [edi.Real_mode_Call._EAX]
Else
xor eax,eax
mov ah,48h
mov bx,512/16
Dosint 21h
jnz Error_vesa
Endif
@@cont:
mov [Seg_Buffer_Vesa],eax
shl eax,4
sub eax,[Code32_Addr]
mov [Addr_Buffer_Vesa],eax
If __Use_Watcom__
mov edi,O DPMI_CALL
mov W [edi.Real_mode_Call._EAX],4f00h
mov [edi.Real_mode_Call._EDI],0h
mov eax,[Seg_Buffer_Vesa]
mov [edi.Real_mode_Call._ES],ax
mov ax,300h
mov bl,10h
xor cx,cx
int 31h
jc Error_vesa
Else
mov eax,[Seg_Buffer_Vesa]
mov [Real_ES],eax
xor edi,edi
mov ax,4f00h
DosInt 10h
cmp ax,004fh
jne Error_vesa
Endif
mov edi,[Addr_Buffer_Vesa]
cmp D [edi],'ASEV'
jnz Error_vesa
───────────────────────────────────────────────────────────────────────────────
Les variables inutilisables sous WATCOM
───────────────────────────────────────────────────────────────────────────────
Real_DS
Real_ES
Real_FS
Real_GS
Real_SS
Real_SS
pour les raisons indiquées plus haut
───────────────────────────────────────────────────────────────────────────────
Différence entre les fichiers sources
───────────────────────────────────────────────────────────────────────────────
Sous E.O.S
Dans un Programme E.O.S le début du programme doit obligatoirement
s'appeler START32.
Sous WATCOM
Un programme peut commencer n'importe où, il suffit juste de préciser
la fin du programme par la commande END <Label>.
Il faut obligatoirement appeler la routine Init_EOS qui émule
les variables de l'E.O.S le plus tôt possible dans le programme.
Le sélecteur ES pointe sur le PSP du Programme.
Exemple de programme WATCOM en assembleur :
Locals
.386
CODE32 SEGMENT PUBLIC PARA 'CODE' USE32
ASSUME CS:CODE32,DS:CODE32,ES:CODE32
INCLUDE ..\RESOURCE\EOS.INC
Msg_Hello db 'Hello World ...',13,10,36
Start32:
call Init_EOS
push ds
pop es
mov ah,9
mov edx,O Msg_Hello
int 21h
mov ax,4c00h
int 21h
CODE32 ENDS
END Start32
Exemple de programme WATCOM en C :
void main()
{
call Init_EOS
printf(" ■ Hello world...\x0D\x0A");
exit(0);
}
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les librairies de l'E.O.S ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Contrairement aux fonctions de l'E.O.S, les appels aux fonctions des
librairies ne se font plus par l'interruption Int_EOS mais par de simple
Call.
Exemple :
mov eax,Mode640x480x256
call Init_Vesa
jc Error_Vesa
Les fonctions disponibles sont les suivantes :
DEBUG.OBJ
┌──────────────────────────────────────────────────────────────────────────┐
│Debug │
│Debug Back │
└──────────────────────────────────────────────────────────────────────────┘
VESA.OBJ
┌──────────────────────────────────────────────────────────────────────────┐
│Init Vesa │
│Init Vesa2 │
│Init Vesa Bank │
│Close Vesa Bank │
│Set Bank │
└──────────────────────────────────────────────────────────────────────────┘
FLI32.OBJ
┌──────────────────────────────────────────────────────────────────────────┐
│Load Fli │
│Load Internal Fli │
│Dispose Fli │
│First Frame Fli │
│Next Frame Fli │
└──────────────────────────────────────────────────────────────────────────┘
SNAP.OBJ
┌──────────────────────────────────────────────────────────────────────────┐
│Init Snap │
│Snap IFF │
│Save IFF │
└──────────────────────────────────────────────────────────────────────────┘
JOYSTICK.OBJ
┌──────────────────────────────────────────────────────────────────────────┐
│Init Joystick │
│Dectect Joystick │
│Add Joystick │
│Update Joystick │
│Sub Joystick │
│Upper Left │
│Lower Right │
│Center │
└──────────────────────────────────────────────────────────────────────────┘
MEMORY.OBJ
┌──────────────────────────────────────────────────────────────────────────┐
│Init Memory │
└──────────────────────────────────────────────────────────────────────────┘
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ La librairie VESA ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
───────────────────────────────────────────────────────────────────────────────
Automatic Bank Switching en VESA 1.0 ou 2.0
───────────────────────────────────────────────────────────────────────────────
La librairie VESA permet de ne pas se soucier de la commutation des
banks en VESA 1.0. On peut écrire ou lire directement dans le buffer vidéo comme
ci-dessous :
Exemple :
call Init_Vesa_Bank ; Mise en place de la commutation
jc Error_Sel ; automatique des banks
mov es,bx ; Positionnement de ES:EDI sur le
xor edi,edi ; buffer vidéo
mov esi,[Addr_Pic] ; Positionnement de DE:ESI sur Addr_Pic
xor edx,edx
call Set_Bank ; Sélection du premier bank
mov ecx,640*(480/4)
rep movsd ; Commutation auto des autres banks
Explication :
En principe, pour accéder à la totalité de la RAM vidéo, vous êtes obligé de
commuter manuellement les banks :
mov esi,Adresse_de_mon_image
mov edx,0
call set_bank
mov ecx,64k
mov edi,0
rep movsd
mov edx,1
call set_bank
mov ecx,64k
mov edi,0
rep movsd
etc..
Cette manipulation est possible avec l'E.O.S et très facile à réaliser pour
une image. Par contre pour des sprites qui se déplacent à l'écran cela
devient très vite plus difficile car le changement de bank peut survenir à
n'importe quel instant. A chaque pixel il faut donc faire un test ce qui
empêche l'utilisation d'instruction comme rep movsd. Inutile de vous dire
que c'est aussi très lent. Avec la commutation automatique de l'E.O.S,
il vous suffit d'indiquer le premier bank. Lorsqu'un changement de bank
doit avoir lieu, par exemple au milieu d'une instruction rep movsd l'E.O.S
commute le bank suivant et repositione le registre EDI et l'instruction
peut alors se poursuivre. Cette méthode est extrêmement rapide et permet
de travailler linéairement sans faire un seul test pour changer de bank.
Attention !
La valeur de EDI dans la routine suivante n'est pas égale
à 65535+4 mais à 00000+3.
...
mov edi,65535
stosd
... ; EDI = 3 !!!
Lorsque E.O.S change de bank, il change aussi la valeur de EDI :
00000 Bank 1
65535 ; edi=65535, bank= 1
65536 Bank 2 ; edi=00000, bank= 2
Restrictions : En lecture, seul les instructions Lodsb, Lodsw et Lodsd
sont supportées.
Pour que le système de commutation fonctionne correctement, il faut donc
respecter les quatres règles suivantes :
1 - Positionner manuellement le premier bank.
2 - Ecrire dans le buffer vidéo de haut en bas.
3 - Prendre en compte le fait que l'EOS peut modifier
EDI ou ESI.
4 - Utiliser uniquement Lodsb, Lodsw et Lodsd pour lire dans
le buffer vidéo.
───────────────────────────────────────────────────────────────────────────────
Linear Frame Buffer en VESA 2.0
───────────────────────────────────────────────────────────────────────────────
En VESA 2.0, l'E.O.S permet d'accéder à un buffer linéaire fictif qui
correspond directement à la mémoire de votre carte graphique. Lorsque vous
écrivez dans ce buffer, l'information est instantanément écrite dans la ram de
la carte vidéo par un système de redirection d'adresse. Le buffer vidéo
fictif ne prend donc aucune place en mémoire RAM puisqu'il est l'image directe
de la mémoire vidéo.
Exemple :
mov eax,Mode640x480x256 ; Init SVGA Mode
mov ecx,640*480 ; Linear Buffer Size
call Init_Vesa2
jc Error_Vesa
mov [Buffer],eax ; Linear Buffer Address
...
mov edi,[Buffer]
mov ecx,(640/4)*480
rep movsd
Cette méthode est beaucoup plus pratique que la commutation de
bank car les registres du processeur ne sont pas modifiés. Malheureusement,
ce système nécessite une carte vidéo très récente car le Linear Frame
Buffer est réalisé en hard par celle-ci.
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les fonctions de la librairie VESA ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
┌───────────────┐
│Init Vesa │
│Init Vesa2 │
│Init Vesa Bank │
│Close Vesa Bank│
│Set Bank │
└───────────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│Init Vesa Initialize A Vesa 1.x or 2.0 to use automatic bank switching │
│ │
│In : │
│ EAX = Vesa mode │
│ │
│Out : │
│ EAX = VRAM address │
│ │
│ Carry = 0 │
│ All Done │
│ │
│ Carry = 1 │
│ Mode Vesa not supported or Vesa driver not found │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov eax,Mode640x480x256
call Init_Vesa
jc Error_Vesa
...
Vesa_Txt db ' ■ Mode SVGA not supported or VESA not found !',13,10
db ' To install a vesa driver, refer to your video card documentation.',13,10,36
┌──────────────────────────────────────────────────────────────────────────┐
│Init Vesa2 Initialize A Vesa 2.0 to use linear frame buffer │
│ │
│In : │
│ EAX = Vesa mode │
│ ECX = Video buffer size │
│ │
│Out : │
│ EAX = Linear buffer address │
│ │
│ Carry = 0 │
│ All Done │
│ │
│ Carry = 1 │
│ Mode Vesa not supported or Vesa driver not found │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov eax,Mode640x480x256
mov ecx,640*480
call Init_Vesa2
jc Error_Vesa
mov [Screen],eax
...
Vesa_Txt db ' ■ Mode SVGA not supported or VESA not found !',13,10
db ' To install a vesa driver, refer to your video card documentation.',13,10,36
┌──────────────────────────────────────────────────────────────────────────┐
│Init Vesa Bank Init the Automatic Bank Switching │
│ │
│In : │
│ │
│Out : │
│ Carry = 0 │
│ All Done │
│ BX = New selector for addressing the video ram │
│ │
│ Carry = 1 │
│ Can't allocate selector │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
call Init_Vesa_Bank
jc Error_Sel
mov [screen_selector],bx
┌──────────────────────────────────────────────────────────────────────────┐
│Close Vesa Bank Close the Automatic Bank Switching │
│ │
│In : │
│ │
│Out : │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
call Close_Vesa_Bank
┌──────────────────────────────────────────────────────────────────────────┐
│Set Bank Select the first Bank │
│ │
│In : │
│ │
│Out : │
│ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov edx,edi ; EDI Address of first pixel to be display
shr edx,16
call Set_Bank
and edi,0ffffh
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les variables de la librairie VESA ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
┌─────────────────────┐
│Vesa Clear Palette │
└─────────────────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│Vesa Clear Palette Toggle clear palette on/off │
│ │
│In : │
│ │
│Out : │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov vesa_clear_palette,off ; Default = On
call Init_Vesa_Bank
jc Error_Sel
mov [screen_selector],bx
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les déclarations de la librairie VESA ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
───────────────────────────────────────────────────────────────────────────────
VBE v1.0
───────────────────────────────────────────────────────────────────────────────
Mode640x400x256 = 100h
Mode640x480x256 = 101h
Mode800x600x16 = 102h
Mode800x600x256 = 103h
Mode1024x768x16 = 104h
Mode1024x768x256 = 105h
Mode1280x1024x16 = 106h
Mode1280x1024x256 = 107h
Mode80x60 = 108h
Mode132x25 = 109h
Mode132x43 = 10ah
Mode132x60 = 10bh
Mode132x60 = 10ch
───────────────────────────────────────────────────────────────────────────────
VBE v1.2+
───────────────────────────────────────────────────────────────────────────────
Mode320x200x32k = 10dh
Mode320x200x64k = 10eh
Mode320x200x16M = 10fh
Mode640x480x32k = 110h
Mode640x480x64k = 111h
Mode640x480x16M = 112h
Mode800x600x32k = 113h
Mode800x600x64k = 114h
Mode800x600x16M = 115h
Mode1024x768x32k = 116h
Mode1024x768x64k = 117h
Mode1024x768x16M = 118h
Mode1280x1024x32k = 119h
Mode1280x1024x64k = 11ah
Mode1280x1024x16M = 11bh
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ La librairie FLI32 ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Cette librairie permet d'utiliser des fichiers 3D précalculé au format FLI
ou FLC dans vos programmes.
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les fonctions de la librairie FLI32 ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
┌─────────────────┐
│Load Fli │
│Load Internal Fli│
│First Frame Fli │
│Next Frame Fli │
│Dispose Fli │
└─────────────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│Play a FLI/FLC files │
│ │
│Functions : │
│ │
│ Load_Fli Load a FLI into the memory │
│ Initialize if needed the track-disk mode │
│ Check the header │
│ │
│ Load_Internal_Fli Load a FLI which is link with LLINK │
│ Check the header │
│ │
│ First_Frame_Fli Uncompress the first frame │
│ │
│ Next_Frame_Fli Uncompress next frame │
│ │
│ Dispose_Fli Freeing memory │
│ Close File │
│ │
│Information During playing : │
│ │
│ Fli_Err = 1 - Chunk not found │
│ 2 - Out of memory │
│ 3 - File error │
│ 4 - Bad FLC header │
│ 5 - Size max for FLC : 640x480 │
│ │
│ Fli_Swap = On - Track disk running - not enough memory to │
│ load the file │
│ Off- File has been load into memory │
│ │
│ Fli_Svga = On - Number of Lines >200 │
│ │
│ Fli_Delay = Fli speed │
│ │
│ Fli_Last_Frame= On - Last frame (Mode No looping) │
│ │
│ Fli_Current_Frame = Current frame │
│ │
│Commands : │
│ │
│ Fli_Selector = Screen selector │
│ │
│ Fli_ReStart = On - Restart at the begining of the animation │
│ │
│ Fli_Loop = On - Restart the FLI at the end (Defaults) │
│ Off- Stop at the end (Mode No looping) │
│ │
│ Fli_TrackDisk = On - Enable Track-Disk mode │
│ Off- Track-Disk not use execpt when the FLI can't │
│ be load into the memory │
│ │
│ Fli_Buffer = Logical address of FLI buffer │
│ │
│ Fli_Ligne_Shl = 6 for 320 per line │
│ 7 for 640 per line │
│ │
│ Fli_Scr_X = Number of pixel per line │
│ Fli_Scr_Y = Number of lines │
│ │
│ Fli_Decal_X = Number of pixel per line │
│ Fli_Decal_Y = Number of lines │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov edx, offset Fli_Path
call Load_Fli
jc Fli_Error
cmp Fli_Svga,On
je @@Init_Svga
jne @@Init_Vga
...
mov Fli_Selector,[screen_selector]
call First_Frame_Fli
jc Fli_Error
@@again:
mov ah,Wait_Vbl
Int_EOS
call Next_Frame_Fli
jc Fli_Error
cmp Key_Map[Escape],On
jne @@again
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ La librairie SNAP ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Cette librairie permet de réaliser des hard-copy d'écran VESA au format IFF
à l'aide de la touche Arrêt_défil.
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les fonctions de la librairie SNAP ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
┌─────────┐
│Init Snap│
│Snap IFF │
│Save IFF │
└─────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│Init Snap Initialize the screen grabber . (You can change the int 09 │
│ function Use_Int_09 after this Init │
│ │
│In : │
│ │
│Out : │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ah,Use_Int_09
mov bx,On
Int_EOS
call Init_Snap
┌──────────────────────────────────────────────────────────────────────────┐
│Snap IFF Grab the current Screen from Video RAM │
│ │
│In : │
│ │
│Out : │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
call Snap_IFF
┌──────────────────────────────────────────────────────────────────────────┐
│Save IFF Save a buffer to IFF │
│ │
│In : │
│ AX = Screen Size X │
│ BX = Screen Size Y │
│ EDX = Offset of File Name │
│ ESI = Address to save in IFF │
│ │
│Out : │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ax,640
mov bx,480
mov edx,O File_Name
mov esi,Buffer
call Save_IFF
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ La librairie JOYSTICK ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Cette librairie permet de gérer des manettes de jeux.
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les fonctions de la librairie JOYSTICK ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
┌────────────────┐
│Init Joystick │
│Dectect Joystick│
│Add Joystick │
│Update Joystick │
│Sub Joystick │
│Upper Left │
│Lower Right │
│Center │
└────────────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│Init_Joystick Initialize all port en address │
│ │
│In : │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
call Init_Joystick
┌──────────────────────────────────────────────────────────────────────────┐
│Dectect_Joystick Find if a analogic joystick is plug in port 1 ,2 or Both│
│ │
│In : │
│ │
│Out : │
│ Carry = 0 │
│ All Done │
│ EAX = 1 A joystick is plug in port 1 │
│ 2 A joystick is plug in port 2 │
│ 3 2 joystick is plug in port 1 and 2 │
│ │
│ Carry = 1 │
│ No Joystick │
│ │
│Other Registers Change : None │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
call Detect_Joystick
test eax,Analog_A
je @@Ok1
...
@@Ok1:
test eax,Analog_B
je @@Ok3
...
@@Ok3:
┌──────────────────────────────────────────────────────────────────────────┐
│Add_Joystick Add a new joystick to be use by the library │
│ │
│In : │
│ AX = Type Of joystick │
│ Analog_A │
│ Analog_B │
│ Lpt_A │
│ Lpt_B │
│ BX = Address of port │
│ = 1 Lpt1 │
│ = 2 Lpt2 │
│ = 3 Lpt3 │
│ = 4 Lpt4 │
│ │
│Out : │
│ Carry = 0 │
│ All Done │
│ ESI = Address of structure of joystick │
│ │
│ Carry = 1 │
│ No Joystick Available │
│ │
│Other Registers Change : None │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov ax,Analog_A
call Add_Joystick
jc No_Joystick_Available
┌──────────────────────────────────────────────────────────────────────────┐
│Update_Joystick Must be call often update all structure of all Joystick │
│ declare with Add_Joystick │
│ │
│In : │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
call Update_Joystick
┌──────────────────────────────────────────────────────────────────────────┐
│Sub_Joystick Delete a Joystick create by Add_Joystick │
│ │
│In : │
│ ESI = Address of structure to be delete │
│ │
│Out : │
│ Carry = 0 │
│ All Done │
│ │
│ Carry = 1 │
│ Structure not found │
│ │
│Other Registers Change : None │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
mov esi,[Addr_Joy1]
call Sub_Joystick
jc Structure_Not_Found
┌──────────────────────────────────────────────────────────────────────────┐
│Upper_Left Take Value For Upper Left Joystick's Coordonate │
│ │
│In : │
│ ESI = Address of structure │
│ │
│Out : │
│ Carry = 0 │
│ All Done │
│ │
│ Carry = 1 │
│ No Fire Press │
│ │
│ │
│Other Registers Change : None │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
@@Loop:
mov esi,[Addr_Joy1]
call Upper_Left
jc @@Loop
┌──────────────────────────────────────────────────────────────────────────┐
│Lower_Right Take Value For Lower Right Joystick's Coordonate │
│ │
│In : │
│ ESI = Address of structure │
│ │
│Out : │
│ Carry = 0 │
│ All Done │
│ │
│ Carry = 1 │
│ No Fire Press │
│ │
│ │
│Other Registers Change : None │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
@@Loop:
mov esi,[Addr_Joy1]
call Lower_Right
jc @@Loop
┌──────────────────────────────────────────────────────────────────────────┐
│Center Take Value For Center Joystick's Coordonate │
│ │
│In : │
│ ESI = Address of structure │
│ │
│Out : │
│ Carry = 0 │
│ All Done │
│ │
│ Carry = 1 │
│ No Fire Press │
│ │
│ │
│Other Registers Change : None │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
@@Loop:
mov esi,[Addr_Joy1]
call Center
jc @@Loop
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les déclarations de la librairie JOYSTICK ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Analog_A = 1h
Analog_B = 2h
Lpt_A = 10h
Lpt_B = 20h
Lpt1 = 1h
Lpt2 = 2h
Lpt3 = 3h
Lpt4 = 4h
Joy Struc
J_Type dw 0
J_Addr dw 0
J_Min_X dw 0
J_Max_X dw 0
J_Min_Y dw 0
J_Max_Y dw 0
J_Center_X dw 0
J_Center_Y dw 0
J_Left db 0
J_Right db 0
J_Up db 0
J_Down db 0
J_Fire1 db 0
J_Fire2 db 0
J_Fire3 db 0
J_Fire4 db 0
Joy ends
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ La librairie mémoire ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Cette librairie affiche la mémoire disponible en temps réel sur l'écran
monochrome.
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les fonctions de la librairie mémoire ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
┌───────────┐
│Init Memory│
└───────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│Init_Memory Turn the display memory on │
│ │
│In : │
│ │
│Out : │
│ │
│Other Registers Change : None │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Exemple :
call Init_Memory
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les fonctions du DPMI (interruption 31h) supportées par l'E.O.S ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Les fonctions DPMI suivantes ne sont disponibles que pour les personnes qui
utilisent les versions WEOS.EXE, WEOSLITE.EXE ou WDEBUG.EXE. C'est à dire
les programmeurs Watcom (C++ ou Assembleur).
Function 0000h - Allocate LDT Descriptors
Function 0001h - Free LDT Descriptor
Function 0002h - Segment to Descriptor
Function 0003h - Get Next Selector Increment Value
Function 0006h - Get Segment Base Address
Function 0007h - Set Segment Base Address
Function 0008h - Set Segment Limit
Function 0009h - Set Descriptor Access Rights
Function 000Ah - Create Code Segment Alias Descriptor
Function 000Bh - Get Descriptor
Function 000Ch - Set Descriptor
Function 0100h - Allocate DOS Memory Block
Function 0101h - Free DOS Memory Block
Function 0102h - Resize DOS Memory Block
Function 0200h - Get Real Mode Interrupt Vector
Function 0201h - Set Real Mode Interrupt Vector
Function 0202h - Get Processor Exception Handler Vector
Function 0203h - Set Processor Exception Handler Vector
Function 0204h - Get Protected Mode Interrupt Vector
Function 0205h - Set Protected Mode Interrupt Vector
Function 0300h - Simulate Real Mode Interrupt
Function 0301h - Call Real Mode Procedure With Far Return Frame
Function 0302h - Call Real Mode Procedure With Iret Frame
Function 0400h - Get Version
Function 0500h - Get Free Memory Information
Function 0501h - Allocate Memory Block
Function 0502h - Free Memory Block
Function 0503h - Resize Memory Block
Function 0800h - Physical Address Mapping
Function 0900h - Get and Disable Virtual Interrupt State
Function 0901h - Get and Enable Virtual Interrupt State
Function 0902h - Get Virtual Interrupt State
───────────────────────────────────────────────────────────────────────────────
Function 0000h - Allocate LDT Descriptors
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0000h
CX = Number of descriptors to allocate
Out:
Carry = 0 if successful
AX = Base selector
───────────────────────────────────────────────────────────────────────────────
Function 0001h - Free LDT Descriptor
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0001h
BX = Selector to free
Out:
Carry = 0 if successful
───────────────────────────────────────────────────────────────────────────────
Function 0002h - Segment to Descriptor
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0002h
BX = Real mode segment address
Out:
Carry = 0 if successful
AX = Selector mapped to real mode segment
───────────────────────────────────────────────────────────────────────────────
Function 0003h - Get Next Selector Increment Value
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0003h
Out:
Carry = 0
AX = Value to add to get to next selector
───────────────────────────────────────────────────────────────────────────────
Function 0006h - Get Segment Base Address
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0006h
BX = Selector
Out:
Carry = 0 if successful
CX:DX = 32-bit linear base address of segment
───────────────────────────────────────────────────────────────────────────────
Function 0007h - Set Segment Base Address
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0007h
BX = Selector
CX:DX = 32-bit linear base address for segment
Out:
Carry = 0 if successful
───────────────────────────────────────────────────────────────────────────────
Function 0008h - Set Segment Limit
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0008h
BX = Selector
CX:DX = 32-bit segment limit
Out:
Carry = 0 if successful
───────────────────────────────────────────────────────────────────────────────
Function 0009h - Set Descriptor Access Rights
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0009h
BX = Selector
CX = rights/type word
Out:
Carry = 0 if successful
Notes:
The access rights/type word passed to the function in CX has
the following format :
Bit: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
┌───┬───┬───┬───┬───────────────┬───┬───────┬───┬───┬───┬───┬───┐
│ G │B/D│ 0 │ 0 │ 0 │ 1 │ DPL │ 1 │C/D│E/C│W/R│ A │
└───┴───┴───┴───┴───────────────┴───┴───────┴───┴───┴───┴───┴───┘
G h - 0=byte granular, 1=page granular
B/Dh - 0=default 16bit, 1=default 32bit
DPLh - must be equal to caller's CPL
C/Dh - 0=data, 1=code
E/Ch - data: 0=expand-up, 1=expand-down
code: must be 0 (non-conforming)
W/Rh - data: 0=read, 1=read/write
code: must be 1 (readable)
A h - 0=not accessed, 1=accessed
───────────────────────────────────────────────────────────────────────────────
Function 000Ah - Create Code Segment Alias Descriptor
───────────────────────────────────────────────────────────────────────────────
In:
AX = 000Ah
BX = Code segment selector
Out:
Carry = 0 if successful
AX = New data selector
───────────────────────────────────────────────────────────────────────────────
Function 000Bh - Get Descriptor
───────────────────────────────────────────────────────────────────────────────
In:
AX = 000Bh
BX = Selector
ES:EDI = Pointer to an 8 byte buffer to receive copy of descriptor
Out:
Carry = 0 if successful
ES:EDI = Pointer to buffer that contains descriptor
───────────────────────────────────────────────────────────────────────────────
Function 000Ch - Set Descriptor
───────────────────────────────────────────────────────────────────────────────
In:
AX = 000Ch
BX = Selector
ES:EDI = Pointer to an 8 byte buffer that contains descriptor
Out:
Carry = 0 if successful
───────────────────────────────────────────────────────────────────────────────
Function 0100h - Allocate DOS Memory Block
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0100h
BX = Number of paragraphs (16 byte blocks) desired
Out:
Carry = 0 if successful
AX = Initial real mode segment of allocated block
DX = Selector for allocated block
Carry = 1 if error
AX = DOS error code:
07h memory control blocks damaged
08h insufficient memory available to allocate as requested
BX = Size of largest available block in paragraphs
───────────────────────────────────────────────────────────────────────────────
Function 0101h - Free DOS Memory Block
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0101h
DX = Selector of block to free
Out:
Carry = 0 if successful
Carry = 1 if error
AX = DOS error code:
07h memory control blocks damaged
09h incorrect memory segment specified
───────────────────────────────────────────────────────────────────────────────
Function 0102h - Resize DOS Memory Block
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0102h
BX = New block size in paragraphs
DX = Selector of block to modify
Out:
Carry = 0 if successful
Carry = 1 if error
AX = DOS error code:
07h memory control blocks damaged
08h insufficient memory available to allocate as requested
09h incorrect memory segment specified
BX = Maximum block size possible in paragraphs
───────────────────────────────────────────────────────────────────────────────
Function 0200h - Get Real Mode Interrupt Vector
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0200h
BL = Interrupt number
Out:
Carry = 0 if successful
CX:DX = Segment:Offset of real mode interrupt handler
───────────────────────────────────────────────────────────────────────────────
Function 0201h - Set Real Mode Interrupt Vector
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0201h
BL = Interrupt number
CX:DX = Segment:Offset of real mode interrupt handler
Out:
Carry = 0 if successful
───────────────────────────────────────────────────────────────────────────────
Function 0202h - Get Processor Exception Handler Vector
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0202h
BL = Exception/fault number (00h-1Fh)
Out:
Carry = 0 if successful
CX:EDX = Selector:Offset of exception handler
───────────────────────────────────────────────────────────────────────────────
Function 0203h - Set Processor Exception Handler Vector
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0203h
BL = Exception/fault number (00h-1Fh)
CX:EDX = Selector:Offset of exception handler
Out:
Carry = 0 if successful
───────────────────────────────────────────────────────────────────────────────
Function 0204h - Get Protected Mode Interrupt Vector
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0204h
BL = Interrupt number
Out:
Carry = 0
CX:EDX = Selector:Offset of exception handler
───────────────────────────────────────────────────────────────────────────────
Function 0205h - Set Protected Mode Interrupt Vector
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0205h
BL = Interrupt number
CX:EDX = Selector:Offset of exception handler
Out:
Carry = 0 if successful
───────────────────────────────────────────────────────────────────────────────
Function 0300h - Simulate Real Mode Interrupt
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0300h
BL = Interrupt number
BH = 0
CX = Number of words to copy from protected mode to real mode stack
ES:EDI = Selector:Offset of real mode call structure
Out:
Carry = 0 if successful
ES:EDI = Selector:Offset of modified real mode call structure
in the folling format:
Offset Length Contents
00h 4 EDI
04h 4 ESI
08h 4 EBP
0ch 4 reserved, should be zero
10h 4 EBX
14h 4 EDX
18h 4 ECX
1ch 4 EAX
20h 2 CPU status flags
22h 2 ES
24h 2 DS
26h 2 FS
28h 2 GS
2ah 2 IP (reserved, ignored)
2ch 2 CS (reserved, ignored)
2eh 2 SP
30h 2 SS
───────────────────────────────────────────────────────────────────────────────
Function 0301h - Call Real Mode Procedure With Far Return Frame
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0301h
BH = 0
CX = Number of words to copy from protected mode to real mode stack
ES:EDI = Selector:Offset of real mode call structure
Out:
Carry = 0 if successful
ES:EDI = Selector:Offset of modified real mode call structure
in the folling format:
Offset Length Contents
00h 4 EDI
04h 4 ESI
08h 4 EBP
0ch 4 reserved, ingored
10h 4 EBX
14h 4 EDX
18h 4 ECX
1ch 4 EAX
20h 2 CPU status flags
22h 2 ES
24h 2 DS
26h 2 FS
28h 2 GS
2ah 2 IP
2ch 2 CS
2eh 2 SP
30h 2 SS
───────────────────────────────────────────────────────────────────────────────
Function 0302h - Call Real Mode Procedure With Iret Frame
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0302h
BH = 0
CX = Number of words to copy from protected mode to real mode stack
ES:EDI = Selector:Offset of real mode call structure
Out:
Carry = 0 if successful
ES:EDI = Selector:Offset of modified real mode call structure
Offset Length Contents
00h 4 EDI
04h 4 ESI
08h 4 EBP
0ch 4 reserved, ingored
10h 4 EBX
14h 4 EDX
18h 4 ECX
1ch 4 EAX
20h 2 CPU status flags
22h 2 ES
24h 2 DS
26h 2 FS
28h 2 GS
2ah 2 IP
2ch 2 CS
2eh 2 SP
30h 2 SS
───────────────────────────────────────────────────────────────────────────────
Function 0400h - Get Version
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0400h
Out:
AH = Major version
AL = Minor version
BX = Flags
CL = Processor type
02 = 80286
03 = 80386
04 = 80486
DH = Current value of virtual master PIC base interrupt
DL = Current value of virtual slave PIC base interrupt
Carry = 0
───────────────────────────────────────────────────────────────────────────────
Function 0500h - Get Free Memory Information
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0500h
ES:EDI = Selector:Offset of 30h byte buffer
Out:
Carry = 0 if successful
ES:EDI = Selector:Offset of buffer with the following structure
───────────────────────────────────────────────────────────────────────────────
Function 0501h - Allocate Memory Block
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0501h
BX:CX = Size of memory block to allocate in bytes
Out:
Carry = 0 if successful
BX:CX = Linear address of allocated memory block
SI:DI = Memory block handle (used to resize and free)
───────────────────────────────────────────────────────────────────────────────
Function 0502h - Free Memory Block
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0502h
SI:DI = Handle of memory block to free
Out:
Carry = 0 if successful
───────────────────────────────────────────────────────────────────────────────
Function 0503h - Resize Memory Block
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0503h
BX:CX = New size of memory block to allocate in bytes
SI:DI = Handle of memory block to resize
Out:
Carry = 0 if successful
BX:CX = New linear address of memory block
SI:DI = New handle of memory block
───────────────────────────────────────────────────────────────────────────────
Function 0800h - Physical Address Mapping
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0800h
BX:CX = Physical address of memory
SI:DI = Size of region to map in bytes
Out:
Carry = 0 if successful
BX:CX = Linear address that can be used to access the physical memory
───────────────────────────────────────────────────────────────────────────────
Function 0900h - Get and Disable Virtual Interrupt State
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0900h
Out:
Carry = 0
AL = 0 if virtual interrupts were previously disabled
AL = 1 if virtual interrupts were previously enabled
───────────────────────────────────────────────────────────────────────────────
Function 0901h - Get and Enable Virtual Interrupt State
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0901h
Out:
Carry = 0
AL = 0 if virtual interrupts were previously disabled
AL = 1 if virtual interrupts were previously enabled
───────────────────────────────────────────────────────────────────────────────
Function 0902h - Get Virtual Interrupt State
───────────────────────────────────────────────────────────────────────────────
In:
AX = 0902h
Out:
Carry = 0
AL = 0 if virtual interrupts are disabled
AL = 1 if virtual interrupts are enabled
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Les fonctions du DOS (interruption 21h) supportées par l'E.O.S ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
Function 1h - Keyboard Input with Echo
Function 2h - Display Output
Function 3h - Wait for Auxiliary Device Input
Function 4h - Auxiliary Output
Function 5h - Printer Output
Function 6h - Direct Console I/O
Function 7h - Direct Console Input Without Echo
Function 8h - Console Input Without Echo
Function 9h - Print String
Function Ah - Buffered Keyboard Input
Function Bh - Check Standard Input Status
Function Ch - Clear Keyboard Buffer and Invoke Keyboard Function
Function Dh - Disk Reset
Function Eh - Select Disk
Function Fh - Open a File Using FCB
Function 10h - Close a File Using FCB
Function 11h - Search for First Entry Using FCB
Function 12h - Search for Next Entry Using FCB
Function 13h - Delete File Using FCB
Function 14h - Sequential Read Using FCB
Function 15h - Sequential Write Using FCB
Function 16h - Create a File Using FCB
Function 17h - Rename a File Using FCB
Function 19h - Get Current Default Drive
Function 1Ah - Set Disk Transfer Address (DTA)
Function 21h - Random Read Using FCB
Function 22h - Random Write Using FCB
Function 23h - Get File Size Using FCB
Function 24h - Set Relative Record Field in FCB
Function 25h - Set Interrupt Vector
Function 27h - Random Block Read Using FCB
Function 28h - Random Block Write Using FCB
Function 2Ah - Get Date
Function 2Bh - Set Date
Function 2Ch - Get Time
Function 2Dh - Set Time
Function 2Eh - Set/Reset Verify Switch
Function 2Fh - Get Disk Transfer Address (DTA)
Function 30h - Get DOS Version Number
Function 33h - Get/Set System Values (Ctl-Break/Boot Drive)
Function 34h - Get Address to DOS Critical Flag
Function 35h - Get Interrupt Vector
Function 36h - Get Disk Free Space
Function 37h - Get/Set Switch Character
Function 39h - Create Subdirectory
Function 3Ah - Remove Subdirectory
Function 3Bh - Change Current Directory
Function 3Ch - Create File Using Handle
Function 3Dh - Open File Using Handle
Function 3Eh - Close File Using Handle
Function 3Fh - Read From File or Device Using Handle
Function 40h - Write To File or Device Using Handle
Function 41h - Delete File
Function 42h - Move File Pointer Using Handle
Function 43h - Get/Set File Attributes
Function 45h - Duplicate File Handle
Function 46h - Force Duplicate File Handle
Function 47h - Get Current Directory
Function 48h - Allocate Memory
Function 49h - Free Allocated Memory
Function 4Ah - Modify Allocated Memory Block (SETBLOCK)
Function 4Bh - Load and Execute Program
Function 4Ch - Terminate Process With Return Code
Function 4Dh - Get Return Code of Sub-process
Function 4Eh - Find First Matching File
Function 4Fh - Find Next Matching File
Function 54h - Get Verify Setting
Function 56h - Rename File
Function 58h - Get/Set Memory Allocation Strategy
Function 59h - Get Extended Error Information
Function 5Ah - Create Temporary File
Function 5Bh - Create File
Function 60h - Get Fully Qualified File Name
───────────────────────────────────────────────────────────────────────────────
Function 1h - Keyboard Input with Echo
───────────────────────────────────────────────────────────────────────────────
In:
AH = 01
Out:
AL = character from standard input device
───────────────────────────────────────────────────────────────────────────────
Function 2h - Display Output
───────────────────────────────────────────────────────────────────────────────
In:
AH = 02
DL = character to output
Out:
───────────────────────────────────────────────────────────────────────────────
Function 3h - Wait for Auxiliary Device Input
───────────────────────────────────────────────────────────────────────────────
In:
AH = 03
Out:
AL = character from the auxiliary device
───────────────────────────────────────────────────────────────────────────────
Function 4h - Auxiliary Output
───────────────────────────────────────────────────────────────────────────────
In:
AH = 04
DL = character to output
Out:
───────────────────────────────────────────────────────────────────────────────
Function 5h - Printer Output
───────────────────────────────────────────────────────────────────────────────
In:
AH = 05
DL = character to output
Out:
───────────────────────────────────────────────────────────────────────────────
Function 6h - Direct Console I/O
───────────────────────────────────────────────────────────────────────────────
In:
AH = 06
DL = (0-FE) character to output
= FF if console input request
Out:
AL = input character if console input request (DL=FF)
ZF = 0 if console request character available (in AL)
= 1 if no character is ready, and function request
was console input
───────────────────────────────────────────────────────────────────────────────
Function 7h - Direct Console Input Without Echo
───────────────────────────────────────────────────────────────────────────────
In:
AH = 07
Out:
AL = character from STDIN
───────────────────────────────────────────────────────────────────────────────
Function 8h - Console Input Without Echo
───────────────────────────────────────────────────────────────────────────────
In:
AH = 08
Out:
AL = character from STDIN
───────────────────────────────────────────────────────────────────────────────
Function 9h - Print String
───────────────────────────────────────────────────────────────────────────────
In:
AH = 09
DS:EDX = pointer to string ending in "$"
Out:
───────────────────────────────────────────────────────────────────────────────
Function Ah - Buffered Keyboard Input
───────────────────────────────────────────────────────────────────────────────
In:
AH = 0A
DS:EDX = pointer to input buffer
Out:
───────────────────────────────────────────────────────────────────────────────
Function Bh - Check Standard Input Status
───────────────────────────────────────────────────────────────────────────────
In:
AH = 0B
Out:
AL = 00 if no character available
= FF if character available
───────────────────────────────────────────────────────────────────────────────
Function Ch - Clear Keyboard Buffer and Invoke Keyboard Function
───────────────────────────────────────────────────────────────────────────────
In:
AH = 0C
AL = 01, 06, 07, 08 or 0A (INT 21 input functions)
Out:
───────────────────────────────────────────────────────────────────────────────
Function Dh - Disk Reset
───────────────────────────────────────────────────────────────────────────────
In:
AH = 0D
Out:
───────────────────────────────────────────────────────────────────────────────
Function Eh - Select Disk
───────────────────────────────────────────────────────────────────────────────
In:
AH = 0E
DL = zero based, drive number (0-25, A:h - Z:)
Out:
AL = one based, total number of logical drives including
hardfiles (1-26)
───────────────────────────────────────────────────────────────────────────────
Function Fh - Open a File Using FCB
───────────────────────────────────────────────────────────────────────────────
In:
AH = 0F
DS:EDX = pointer to unopened FCB
Out:
AL = 00 if file opened
= FF if unable to open
───────────────────────────────────────────────────────────────────────────────
Function 10h - Close a File Using FCB
───────────────────────────────────────────────────────────────────────────────
In:
AH = 10h
DS:EDX = pointer to opened FCB
Out:
AL = 00 if file closed
= FF if file not closed
───────────────────────────────────────────────────────────────────────────────
Function 11h - Search for First Entry Using FCB
───────────────────────────────────────────────────────────────────────────────
In:
AH = 11h
DS:EDX = pointer to unopened FCB
Out:
AL = 00 if matching file found
= FF if file not found
───────────────────────────────────────────────────────────────────────────────
Function 12h - Search for Next Entry Using FCB
───────────────────────────────────────────────────────────────────────────────
In:
AH = 12h
DS:EDX = pointer to unopened FCB
Out:
AL = 00 if file found
= FF if file not found
───────────────────────────────────────────────────────────────────────────────
Function 13h - Delete File Using FCB
───────────────────────────────────────────────────────────────────────────────
In:
AH = 13h
DS:EDX = pointer to an unopened FCB
Out:
AL = 00 if file deleted
= FF if file not found
───────────────────────────────────────────────────────────────────────────────
Function 14h - Sequential Read Using FCB
───────────────────────────────────────────────────────────────────────────────
In:
AH = 14h
DS:EDX = pointer to an opened FCB
Out:
AL = 00 if successful read
= 01 if end of file (no data read)
= 02 if DTA is too small
= 03 if end of file or partial record read
───────────────────────────────────────────────────────────────────────────────
Function 15h - Sequential Write Using FCB
───────────────────────────────────────────────────────────────────────────────
In:
AH = 15h
DS:EDX = pointer to an opened FCB
Out:
AL = 00 if write was successful
= 01 if diskette is full or read only
= 02 if DTA is too small
───────────────────────────────────────────────────────────────────────────────
Function 16h - Create a File Using FCB
───────────────────────────────────────────────────────────────────────────────
In:
AH = 16h
DS:EDX = pointer to an unopened FCB
Out:
AL = 00 if file created
= FF if file creation failed
───────────────────────────────────────────────────────────────────────────────
Function 17h - Rename a File Using FCB
───────────────────────────────────────────────────────────────────────────────
In:
AH = 17h
DS:EDX = pointer to a modified FCB
Out:
AL = 00 if file renamed
= FF if file not renamed
───────────────────────────────────────────────────────────────────────────────
Function 19h - Get Current Default Drive
───────────────────────────────────────────────────────────────────────────────
In:
AH = 19h
Out:
AL = current default drive (0=A,1=B,etc)
───────────────────────────────────────────────────────────────────────────────
Function 1Ah - Set Disk Transfer Address (DTA)
───────────────────────────────────────────────────────────────────────────────
In:
AH = 1A
DS:EDX = pointer to DTA
Out:
───────────────────────────────────────────────────────────────────────────────
Function 21h - Random Read Using FCB
───────────────────────────────────────────────────────────────────────────────
In:
AH = 21h
DS:EDX = pointer to an opened FCB
Out:
AL = 00 if read successful
= 01 if EOF (no data read)
= 02 if DTA is too small
= 03 if EOF (partial record read)
───────────────────────────────────────────────────────────────────────────────
Function 22h - Random Write Using FCB
───────────────────────────────────────────────────────────────────────────────
In:
AH = 22h
DS:EDX = far pointer to an opened FCB
Out:
AL = 00 if write successful
= 01 if diskette full or read only
= 02 if DTA is too small
───────────────────────────────────────────────────────────────────────────────
Function 23h - Get File Size Using FCB
───────────────────────────────────────────────────────────────────────────────
In:
AH = 23h
DS:EDX = pointer to an unopened FCB
Out:
AL = 00 if successful
= FF if file not found
───────────────────────────────────────────────────────────────────────────────
Function 24h - Set Relative Record Field in FCB
───────────────────────────────────────────────────────────────────────────────
In:
AH = 24h
DS:EDX = pointer to an opened FCB
Out:
───────────────────────────────────────────────────────────────────────────────
Function 25h - Set Interrupt Vector
───────────────────────────────────────────────────────────────────────────────
In:
AH = 25h
AL = interrupt number
DS:EDX = pointer to interrupt handler
Out:
───────────────────────────────────────────────────────────────────────────────
Function 27h - Random Block Read Using FCB
───────────────────────────────────────────────────────────────────────────────
In:
AH = 27h
CX = number of records to read
DS:EDX = pointer to an opened FCB
Out:
AL = 00 if read was successful
= 01 if EOF (no data read)
= 02 if DTA is too small
= 03 if EOF (partial record read)
CX = actual number of records read
───────────────────────────────────────────────────────────────────────────────
Function 28h - Random Block Write Using FCB
───────────────────────────────────────────────────────────────────────────────
In:
AH = 28h
CX = number of records to write
DS:EDX = pointer to an opened FCB
Out:
AL = 00 if write successful
= 01 if diskette full or read only
= 02 if DTA is too small
CX = number of records written
───────────────────────────────────────────────────────────────────────────────
Function 2Ah - Get Date
───────────────────────────────────────────────────────────────────────────────
In:
AH = 2A
Out:
AL = day of the week (0=Sunday)
CX = year (1980-2099)
DH = month (1-12)
DL = day (1-31)
───────────────────────────────────────────────────────────────────────────────
Function 2Bh - Set Date
───────────────────────────────────────────────────────────────────────────────
IN:
AH = 2B
CX = year (1980-2099)
DH = month (1-12)
DL = day (1-31)
Out:
AL = 00 if date change successful
= FF if invalid date
───────────────────────────────────────────────────────────────────────────────
Function 2Ch - Get Time
───────────────────────────────────────────────────────────────────────────────
In:
AH = 2C
Out:
CH = hour (0-23)
CL = minutes (0-59)
DH = seconds (0-59)
DL = hundredths (0-99)
───────────────────────────────────────────────────────────────────────────────
Function 2Dh - Set Time
───────────────────────────────────────────────────────────────────────────────
In:
AH = 2D
CH = hour (0-23)
CL = minutes (0-59)
DH = seconds (0-59)
DL = hundredths (0-99)
Out:
AL = 00 if time change successful
= FF if time invalid
───────────────────────────────────────────────────────────────────────────────
Function 2Eh - Set/Reset Verify Switch
───────────────────────────────────────────────────────────────────────────────
In:
AH = 2E
AL = 00 to set off
= 01 to set verify on
DH = 00 for DOS versions before 3.0
Out:
───────────────────────────────────────────────────────────────────────────────
Function 2Fh - Get Disk Transfer Address (DTA)
───────────────────────────────────────────────────────────────────────────────
In:
AH = 2F
Out:
ES:EBX = pointer to current DTA
───────────────────────────────────────────────────────────────────────────────
Function 30h - Get DOS Version Number
───────────────────────────────────────────────────────────────────────────────
In:
AH = 30h
Out:
AL = major version number (2-5)
AH = minor version number (in hundredths decimal)
───────────────────────────────────────────────────────────────────────────────
Function 33h - Get/Set System Values (Ctl-Break/Boot Drive)
───────────────────────────────────────────────────────────────────────────────
In:
AH = 33h
AL = 00 to get Ctrl-Break checking flag
= 01 to set Ctrl-Break checking flag
= 02 to set extended Ctrl-Break checking
= 05 get boot drive
DL = 00 to set Ctrl-Break checking off
= 01 to set Ctrl-Break checking on
= boot drive for subfunction 5
Out:
DL = 00 Ctrl-Break checking OFF (AL=0 or AL=2)
= 01 Ctrl-Break checking ON (AL=0 or AL=2)
= boot drive number (1-26, A:h - Z:) (AL=5)
───────────────────────────────────────────────────────────────────────────────
Function 34h - Get Address to DOS Critical Flag
───────────────────────────────────────────────────────────────────────────────
In:
AH = 34h
Out:
ES:EBX = address of a byte indicating whether a DOS call is
in progress. No DOS calls should be made if set.
───────────────────────────────────────────────────────────────────────────────
Function 35h - Get Interrupt Vector
───────────────────────────────────────────────────────────────────────────────
In:
AH = 35h
AL = interrupt vector number
Out:
ES:EBX = pointer to interrupt handler
───────────────────────────────────────────────────────────────────────────────
Function 36h - Get Disk Free Space
───────────────────────────────────────────────────────────────────────────────
In:
AH = 36h
DL = drive number
Out:
AX = sectors per cluster
= FFFF if drive is invalid
BX = number of available clusters
CX = number of bytes per sector
DX = number of clusters per drive
───────────────────────────────────────────────────────────────────────────────
Function 37h - Get/Set Switch Character
───────────────────────────────────────────────────────────────────────────────
In:
AH = 37h
AL = 0 get switch character into DL; some systems return "-"
= 1 set switch character to value in DL
= 2 read device prefix flag into DL; returns DL = 0 indicating
devices must be accessed using /DEV/device. A non-zero value
indicates devices may be accessed without prefix
= 3 set device prefix flag, device names must begin with \DEV\.
DL = new switch character (AL=1)
= 00 \DEV\ must preceed device names (AL=3)
= 01 \DEV\ is not neccesary in device names (AL=3)
Out:
AL = FF illegal subfunction code specified
DL = current switch character (AL=0)
= device availability (AL=2, always FF with DOS 4.x+)
───────────────────────────────────────────────────────────────────────────────
Function 39h - Create Subdirectory
───────────────────────────────────────────────────────────────────────────────
In:
AH = 39h
DS:EDX = pointer to ASCIIZ path name
Out:
Carry = 0 if successful
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 3Ah - Remove Subdirectory
───────────────────────────────────────────────────────────────────────────────
In:
AH = 3A
DS:EDX = pointer to ASCIIZ path name
Out:
Carry = 0 if successful
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 3Bh - Change Current Directory
───────────────────────────────────────────────────────────────────────────────
In:
AH = 3B
DS:EDX = pointer to ASCIIZ path name
Out:
Carry = 0 if successful
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 3Ch - Create File Using Handle
───────────────────────────────────────────────────────────────────────────────
AH = 3C
CX = file attribute
DS:EDX = pointer to ASCIIZ path name
Out:
Carry = 0 if successful
AX = files handle
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 3Dh - Open File Using Handle
───────────────────────────────────────────────────────────────────────────────
AH = 3D
AL = open access mode
DS:EDX = pointer to an ASCIIZ file name
Out:
Carry = 0 if successful
AX = files handle
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 3Eh - Close File Using Handle
───────────────────────────────────────────────────────────────────────────────
In:
AH = 3E
BX = file handle to close
Out:
Carry = 0 if successful
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 3Fh - Read From File or Device Using Handle
───────────────────────────────────────────────────────────────────────────────
In:
AH = 3F
BX = file handle
ECX = number of bytes to read
DS:EDX = pointer to read buffer
Out:
Carry = 0 if successful
EAX = Number of bytes readen
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 40h - Write To File or Device Using Handle
───────────────────────────────────────────────────────────────────────────────
In:
AH = 40h
BX = file handle
ECX = number of bytes to write
DS:EDX = pointer to write buffer
Out:
Carry = 0 if successful
EAX = Number of bytes written
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 41h - Delete File
───────────────────────────────────────────────────────────────────────────────
In:
AH = 41h
DS:EDX = pointer to an ASCIIZ filename
Out:
Carry = 0 if successful
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 42h - Move File Pointer Using Handle
───────────────────────────────────────────────────────────────────────────────
In:
AH = 42h
AL = origin of move
BX = file handle
CX = high order word of number of bytes to move
DX = low order word of number of bytes to move
Out:
Carry = 0 if successful
DX:AX = new pointer location
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 43h - Get/Set File Attributes
───────────────────────────────────────────────────────────────────────────────
In:
AH = 43h
AL = 00 to get attribute
= 01 to set attribute
DS:EDX = pointer to an ASCIIZ path name
CX = attribute to set
Out:
Carry = 0 if successful
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 45h - Duplicate File Handle
───────────────────────────────────────────────────────────────────────────────
In:
AH = 45h
BX = file handle
Out:
Carry = 0 if successful
AX = New handle
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 46h - Force Duplicate File Handle
───────────────────────────────────────────────────────────────────────────────
In:
AH = 46h
BX = existing file handle
CX = second file handle
Out:
Carry = 0 if successful
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 47h - Get Current Directory
───────────────────────────────────────────────────────────────────────────────
In:
AH = 47h
DL = drive number
DS:ESI = pointer to a 64 byte user buffer
Out:
Carry = 0 if successful
DS:ESI = pointer ASCIIZ directory path string
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 48h - Allocate Memory
───────────────────────────────────────────────────────────────────────────────
In:
AH = 48h
BX = number of memory paragraphs requested
Out:
Carry = 0 if successful
EAX = selector for memory block
EBX = ??????
Carry = 1 if error
EAX = error code
EBX = size in paras of the largest block of memory available
Notes:
EBX may be random
───────────────────────────────────────────────────────────────────────────────
Function 49h - Free Allocated Memory
───────────────────────────────────────────────────────────────────────────────
In:
AH = 49h
ES = selector of the memory block
Out:
Carry = 0 if successful
EBX = ??????
Carry = 1 if error
EAX = error code
Notes:
EBX may be random
───────────────────────────────────────────────────────────────────────────────
Function 4Ah - Modify Allocated Memory Block (SETBLOCK)
───────────────────────────────────────────────────────────────────────────────
In:
AH = 4A
BX = new requested block size in paragraphs
ES = segment of the block (~MCB~ + 1 para)
Out:
Carry = 0 if successful
EBX = ??????
Carry = 1 if error
EAX = error code
EBX = size in paras of the largest block of memory available
───────────────────────────────────────────────────────────────────────────────
Function 4Bh - Load and Execute Program
───────────────────────────────────────────────────────────────────────────────
In:
AH = 4B
AL = 00 to load and execute program
DS:EDX = pointer to an ASCIIZ filename
ES:EBX = pointer to a parameter block
Out:
Carry = 0 if successful
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 4Ch - Terminate Process With Return Code
───────────────────────────────────────────────────────────────────────────────
In:
AH = 4C
AL = return code
Out:
───────────────────────────────────────────────────────────────────────────────
Function 4Dh - Get Return Code of Sub-process
───────────────────────────────────────────────────────────────────────────────
In:
AH = 4D
Out:
AH = system exit code (indicates normal termination)
= 00 for normal termination
= 01 if terminated by ctl-break
= 02 if critical device error
AL = child exit code
───────────────────────────────────────────────────────────────────────────────
Function 4Eh - Find First Matching File
───────────────────────────────────────────────────────────────────────────────
In:
AH = 4E
CX = attribute used during search
DS:EDX = pointer to ASCIIZ filespec
Out:
Carry = 0 if successful
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 4Fh - Find Next Matching File
───────────────────────────────────────────────────────────────────────────────
In:
AH = 4F
DS:EDX = unchanged from previous function 4E
Out:
Carry = 0 if successful
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 54h - Get Verify Setting
───────────────────────────────────────────────────────────────────────────────
In:
AH = 54h
Out:
AL = 00 verify off
= 01 verify on
───────────────────────────────────────────────────────────────────────────────
Function 56h - Rename File
───────────────────────────────────────────────────────────────────────────────
In:
AH = 56h
DS:EDX = pointer to old ASCIIZ path/filename
ES:EDI = pointer to new ASCIIZ path/filename
Out:
Carry = 0 if successful
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 58h - Get/Set Memory Allocation Strategy
───────────────────────────────────────────────────────────────────────────────
In:
AH = 58h
AL = 00 get strategy code
= 01 set strategy code
BX = strategy code (when AL = 01)
= 00 first fit (default)
= 01 best fit
= 02 last fit
Out:
Carry = 0 if successful
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 59h - Get Extended Error Information
───────────────────────────────────────────────────────────────────────────────
In:
AH = 59h
BX = 00
Out:
Carry = 0 if successful
AX = error code
BH = error class
BL = suggested action
CH = locus
Carry = 1 if error
───────────────────────────────────────────────────────────────────────────────
Function 5Ah - Create Temporary File
───────────────────────────────────────────────────────────────────────────────
In:
AH = 5A
CX = attribute
DS:EDX = pointer to ASCIIZ path ending in '\'
Out:
Carry = 0 if successful
AX = handle
DS:EDX = pointer to updated ASCIIZ filespec
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 5Bh - Create File
───────────────────────────────────────────────────────────────────────────────
AH = 5B
CX = attribute
DS:EDX = pointer to ASCIIZ path/filename
Carry = 0 if successful
AX = handle
Carry = 1 if error
EAX = error code
───────────────────────────────────────────────────────────────────────────────
Function 60h - Get Fully Qualified File Name
───────────────────────────────────────────────────────────────────────────────
In:
AH = 60h
DS:ESI = pointer to ASCIIZ string containing unqualified filename
ES:EDI = pointer to 128 byte buffer to contain fully qualified filename
Out:
Carry = 0 if successful
ES:EDI = address of fully qualified filename string
Carry = 1 if error
EAX = error code
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Fin de la documentation EOS ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝